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.*;
022import gudusoft.gsqlparser.nodes.couchbase.TObjectConstruct;
023import gudusoft.gsqlparser.nodes.couchbase.TPair;
024import gudusoft.gsqlparser.nodes.functions.TJsonObjectFunction;
025import gudusoft.gsqlparser.nodes.hive.THiveTransformClause;
026import gudusoft.gsqlparser.nodes.hive.THiveTransformClause.ETransformType;
027import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
028import gudusoft.gsqlparser.sqlenv.TSQLEnv;
029import gudusoft.gsqlparser.sqlenv.TSQLSchema;
030import gudusoft.gsqlparser.sqlenv.TSQLSchemaObject;
031import gudusoft.gsqlparser.sqlenv.TSQLTable;
032import gudusoft.gsqlparser.sqlenv.parser.TJSONSQLEnvParser;
033import gudusoft.gsqlparser.stmt.*;
034import gudusoft.gsqlparser.stmt.db2.TDb2ReturnStmt;
035import gudusoft.gsqlparser.stmt.db2.TDb2SqlVariableDeclaration;
036import gudusoft.gsqlparser.stmt.hive.THiveLoad;
037import gudusoft.gsqlparser.stmt.mssql.*;
038import gudusoft.gsqlparser.stmt.mysql.TLoadDataStmt;
039import gudusoft.gsqlparser.stmt.oracle.TBasicStmt;
040import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreatePackage;
041import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateTrigger;
042import gudusoft.gsqlparser.stmt.oracle.TPlsqlRecordTypeDefStmt;
043import gudusoft.gsqlparser.stmt.oracle.TPlsqlTableTypeDefStmt;
044import gudusoft.gsqlparser.stmt.redshift.TRedshiftCopy;
045import gudusoft.gsqlparser.stmt.redshift.TRedshiftDeclare;
046import gudusoft.gsqlparser.stmt.snowflake.*;
047import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure;
048import gudusoft.gsqlparser.util.*;
049import gudusoft.gsqlparser.util.json.JSON;
050
051import javax.script.ScriptEngine;
052import javax.script.ScriptEngineManager;
053import javax.script.ScriptException;
054import java.io.*;
055import java.util.*;
056import java.util.concurrent.atomic.AtomicInteger;
057import java.util.regex.Matcher;
058import java.util.regex.Pattern;
059import java.util.stream.Collector;
060import java.util.stream.Collectors;
061
062import static gudusoft.gsqlparser.EJoinType.right;
063
064@SuppressWarnings("rawtypes")
065public class DataFlowAnalyzer implements IDataFlowAnalyzer {
066
067        private static final Logger logger = LoggerFactory.getLogger(DataFlowAnalyzer.class);
068
069        private static final List<String> TERADATA_BUILTIN_FUNCTIONS = Arrays
070                        .asList(new String[] { "ACCOUNT", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
071                                        "CURRENT_USER", "DATABASE", "DATE", "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", });
072
073        private static final List<String> CONSTANT_BUILTIN_FUNCTIONS = Arrays.asList(new String[] { "ACCOUNT",
074                        "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "DATABASE", "DATE",
075                        "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", "GETDATE" });
076
077        private Stack<TCustomSqlStatement> stmtStack = new Stack<TCustomSqlStatement>();
078        private List<ResultSet> appendResultSets = new ArrayList<ResultSet>();
079        private Set<TCustomSqlStatement> accessedStatements = new HashSet<TCustomSqlStatement>();
080        private Set<TSelectSqlStatement> accessedSubqueries = new HashSet<TSelectSqlStatement>();
081        private Map<String, TCustomSqlStatement> viewDDLMap = new HashMap<String, TCustomSqlStatement>();
082        private Map<String, TCustomSqlStatement> procedureDDLMap = new HashMap<String, TCustomSqlStatement>();
083
084        private SqlInfo[] sqlInfos;
085        private List<ErrorInfo> errorInfos = new ArrayList<ErrorInfo>();
086        private IndexedLinkedHashMap<String, List<SqlInfo>> sqlInfoMap = new IndexedLinkedHashMap<String, List<SqlInfo>>();
087        private TSQLEnv sqlenv = null;
088        private ModelBindingManager modelManager = new ModelBindingManager();
089        private ModelFactory modelFactory = new ModelFactory(modelManager);
090        private List<Long> tableIds = new ArrayList<Long>();
091        private TTableList hiveFromTables;
092        private dataflow dataflow;
093        private String dataflowString;
094        private Option option = new Option();
095
096        {
097                modelManager.TABLE_COLUMN_ID = option.getStartId();
098                modelManager.RELATION_ID = option.getStartId();
099                ModelBindingManager.set(modelManager);
100                ModelBindingManager.setGlobalStmtStack(stmtStack);
101                ModelBindingManager.setGlobalOption(option);
102                ModelBindingManager.setGlobalSqlInfo(sqlInfoMap);
103        }
104
105        public DataFlowAnalyzer(String sqlContent, Option option) {
106                SqlInfo[] sqlInfos = new SqlInfo[1];
107                SqlInfo info = new SqlInfo();
108                info.setSql(sqlContent);
109                info.setOriginIndex(0);
110                sqlInfos[0] = info;
111                this.option = option;
112                ModelBindingManager.setGlobalOption(this.option);
113                this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
114        }
115
116        public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput, String defaultServer,
117                        String defaultDatabase, String defaltSchema) {
118                SqlInfo[] sqlInfos = new SqlInfo[1];
119                SqlInfo info = new SqlInfo();
120                info.setSql(sqlContent);
121                info.setOriginIndex(0);
122                sqlInfos[0] = info;
123                option.setVendor(dbVendor);
124                option.setSimpleOutput(simpleOutput);
125                option.setDefaultServer(defaultServer);
126                option.setDefaultDatabase(defaultDatabase);
127                option.setDefaultSchema(defaltSchema);
128                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
129        }
130
131        public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput) {
132                SqlInfo[] sqlInfos = new SqlInfo[1];
133                SqlInfo info = new SqlInfo();
134                info.setSql(sqlContent);
135                info.setOriginIndex(0);
136                sqlInfos[0] = info;
137                option.setVendor(dbVendor);
138                option.setSimpleOutput(simpleOutput);
139                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
140        }
141
142        public DataFlowAnalyzer(String[] sqlContents, Option option) {
143                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
144                for (int i = 0; i < sqlContents.length; i++) {
145                        SqlInfo info = new SqlInfo();
146                        info.setSql(sqlContents[i]);
147                        info.setOriginIndex(0);
148                        sqlInfos[i] = info;
149                }
150                this.option = option;
151                ModelBindingManager.setGlobalOption(this.option);
152                this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
153        }
154
155        public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput, String defaultServer,
156                        String defaultDatabase, String defaltSchema) {
157                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
158                for (int i = 0; i < sqlContents.length; i++) {
159                        SqlInfo info = new SqlInfo();
160                        info.setSql(sqlContents[i]);
161                        info.setOriginIndex(0);
162                        sqlInfos[i] = info;
163                }
164                option.setVendor(dbVendor);
165                option.setSimpleOutput(simpleOutput);
166                option.setDefaultServer(defaultServer);
167                option.setDefaultDatabase(defaultDatabase);
168                option.setDefaultSchema(defaltSchema);
169                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
170        }
171
172        public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput) {
173                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
174                for (int i = 0; i < sqlContents.length; i++) {
175                        SqlInfo info = new SqlInfo();
176                        info.setSql(sqlContents[i]);
177                        info.setOriginIndex(0);
178                        sqlInfos[i] = info;
179                }
180                option.setVendor(dbVendor);
181                option.setSimpleOutput(simpleOutput);
182                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
183        }
184
185        public DataFlowAnalyzer(SqlInfo[] sqlInfos, Option option) {
186                this.sqlInfos = sqlInfos;
187                this.option = option;
188                ModelBindingManager.setGlobalOption(this.option);
189        }
190
191        public DataFlowAnalyzer(SqlInfo[] sqlInfos, EDbVendor dbVendor, boolean simpleOutput) {
192                this.sqlInfos = sqlInfos;
193                option.setVendor(dbVendor);
194                option.setSimpleOutput(simpleOutput);
195        }
196
197        public DataFlowAnalyzer(File[] sqlFiles, Option option) {
198                SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length];
199                for (int i = 0; i < sqlFiles.length; i++) {
200                        SqlInfo info = new SqlInfo();
201                        info.setSql(SQLUtil.getFileContent(sqlFiles[i]));
202                        info.setFileName(sqlFiles[i].getName());
203                        info.setFilePath(sqlFiles[i].getAbsolutePath());
204                        info.setOriginIndex(0);
205                        sqlInfos[i] = info;
206                }
207                this.sqlInfos = sqlInfos;
208                this.option = option;
209                ModelBindingManager.setGlobalOption(this.option);
210        }
211
212        public DataFlowAnalyzer(File[] sqlFiles, EDbVendor dbVendor, boolean simpleOutput) {
213                SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length];
214                for (int i = 0; i < sqlFiles.length; i++) {
215                        SqlInfo info = new SqlInfo();
216                        info.setSql(SQLUtil.getFileContent(sqlFiles[i]));
217                        info.setFileName(sqlFiles[i].getName());
218                        info.setFilePath(sqlFiles[i].getAbsolutePath());
219                        info.setOriginIndex(0);
220                        sqlInfos[i] = info;
221                }
222                this.sqlInfos = sqlInfos;
223                option.setVendor(dbVendor);
224                option.setSimpleOutput(simpleOutput);
225        }
226
227        public DataFlowAnalyzer(File sqlFile, Option option) {
228                File[] children = SQLUtil.listFiles(sqlFile);
229                SqlInfo[] sqlInfos = new SqlInfo[children.length];
230                for (int i = 0; i < children.length; i++) {
231                        SqlInfo info = new SqlInfo();
232                        info.setSql(SQLUtil.getFileContent(children[i]));
233                        info.setFileName(children[i].getName());
234                        info.setFilePath(children[i].getAbsolutePath());
235                        info.setOriginIndex(0);
236                        sqlInfos[i] = info;
237                }
238                this.sqlInfos = sqlInfos;
239                this.option = option;
240                ModelBindingManager.setGlobalOption(this.option);
241        }
242
243        public DataFlowAnalyzer(File sqlFile, EDbVendor dbVendor, boolean simpleOutput) {
244                File[] children = SQLUtil.listFiles(sqlFile);
245                SqlInfo[] sqlInfos = new SqlInfo[children.length];
246                for (int i = 0; i < children.length; i++) {
247                        SqlInfo info = new SqlInfo();
248                        info.setSql(SQLUtil.getFileContent(children[i]));
249                        info.setFileName(children[i].getName());
250                        info.setFilePath(children[i].getAbsolutePath());
251                        info.setOriginIndex(0);
252                        sqlInfos[i] = info;
253                }
254                this.sqlInfos = sqlInfos;
255                option.setVendor(dbVendor);
256                option.setSimpleOutput(simpleOutput);
257        }
258
259        public boolean isIgnoreRecordSet() {
260                return option.isIgnoreRecordSet();
261        }
262
263        public void setIgnoreRecordSet(boolean ignoreRecordSet) {
264                option.setIgnoreRecordSet(ignoreRecordSet);
265        }
266
267        public boolean isSimpleShowTopSelectResultSet() {
268                return option.isSimpleShowTopSelectResultSet();
269        }
270
271        public void setSimpleShowTopSelectResultSet(boolean simpleShowTopSelectResultSet) {
272                option.setSimpleShowTopSelectResultSet(simpleShowTopSelectResultSet);
273        }
274
275        public boolean isSimpleShowFunction() {
276                return option.isSimpleShowFunction();
277        }
278
279        public void setSimpleShowFunction(boolean simpleShowFunction) {
280                option.setSimpleShowFunction(simpleShowFunction);
281        }
282
283        public boolean isShowJoin() {
284                return option.isShowJoin();
285        }
286
287        public void setShowJoin(boolean showJoin) {
288                option.setShowJoin(showJoin);
289        }
290
291        public void setShowCallRelation(boolean showCallRelation) {
292                option.setShowCallRelation(showCallRelation);
293        }
294
295        public boolean isShowCallRelation() {
296                return option.isShowCallRelation();
297        }
298
299        public boolean isShowImplicitSchema() {
300                return option.isShowImplicitSchema();
301        }
302
303        public void setShowImplicitSchema(boolean showImplicitSchema) {
304                option.setShowImplicitSchema(showImplicitSchema);
305        }
306
307        public boolean isShowConstantTable() {
308                return option.isShowConstantTable();
309        }
310
311        public void setShowConstantTable(boolean showConstantTable) {
312                option.setShowConstantTable(showConstantTable);
313        }
314
315        public boolean isShowCountTableColumn() {
316                return option.isShowCountTableColumn();
317        }
318
319        public void setShowCountTableColumn(boolean showCountTableColumn) {
320                option.setShowCountTableColumn(showCountTableColumn);
321        }
322
323        public boolean isTransform() {
324                return option.isTransform();
325        }
326
327        public void setTransform(boolean transform) {
328                option.setTransform(transform);
329                if (option.isTransformCoordinate()) {
330                        option.setTransform(true);
331                }
332        }
333
334        public boolean isTransformCoordinate() {
335                return option.isTransformCoordinate();
336        }
337
338        public void setTransformCoordinate(boolean transformCoordinate) {
339                option.setTransformCoordinate(transformCoordinate);
340                if (transformCoordinate) {
341                        option.setTransform(true);
342                }
343        }
344
345        public boolean isLinkOrphanColumnToFirstTable() {
346                return option.isLinkOrphanColumnToFirstTable();
347        }
348
349        public void setLinkOrphanColumnToFirstTable(boolean linkOrphanColumnToFirstTable) {
350                option.setLinkOrphanColumnToFirstTable(linkOrphanColumnToFirstTable);
351        }
352
353        public boolean isIgnoreTemporaryTable() {
354                return option.isIgnoreTemporaryTable();
355        }
356
357        public void setIgnoreTemporaryTable(boolean ignoreTemporaryTable) {
358                option.setIgnoreTemporaryTable(ignoreTemporaryTable);
359        }
360        
361        public boolean isIgnoreCoordinate() {
362                return option.isIgnoreCoordinate();
363        }
364
365        public void setIgnoreCoordinate(boolean ignoreCoordinate) {
366                option.setIgnoreCoordinate(ignoreCoordinate);
367        }
368
369        public void setHandleListener(DataFlowHandleListener listener) {
370                option.setHandleListener(listener);
371        }
372
373        public void setSqlEnv(TSQLEnv sqlenv) {
374                this.sqlenv = sqlenv;
375        }
376
377        public void setOption(Option option) {
378                this.option = option;
379                ModelBindingManager.setGlobalOption(this.option);
380        }
381
382        public Option getOption() {
383                return option;
384        }
385
386        public synchronized String chechSyntax() {
387                StringBuilder builder = new StringBuilder();
388                if (sqlInfos != null) {
389                        for (SqlInfo sqlInfo : sqlInfos) {
390                                String content = sqlInfo.getSql();
391                                if (content != null && content.indexOf("<dlineage") != -1) {
392                                        try {
393                                                XML2Model.loadXML(dataflow.class, content);
394                                                continue;
395                                        } catch (Exception e) {
396                                                builder.append("Parsing dataflow ").append("occurs errors.\n").append(e.getMessage())
397                                                                .append("\n");
398                                        }
399                                }
400                                if (content != null && content.trim().startsWith("{")) {
401                                        Map queryObject = (Map) JSON.parseObject(content);
402                                        content = (String) queryObject.get("sourceCode");
403                                }
404                                if (MetadataReader.isMetadata(content)) {
405                                        continue;
406                                }
407                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
408                                sqlparser.sqltext = content;
409                                int result = sqlparser.parse();
410                                if (result != 0) {
411                                        builder.append("Parsing sql ").append("occurs errors.\n").append(sqlparser.getErrormessage())
412                                                        .append("\n");
413                                }
414                        }
415                }
416                return builder.toString();
417        }
418
419        public synchronized String generateDataFlow(boolean withExtraInfo) {
420                if (ModelBindingManager.get() == null) {
421                        ModelBindingManager.set(modelManager);
422                }
423
424                dataflow = analyzeSqlScript();
425
426                if (dataflow != null && !withExtraInfo && dataflow.getResultsets() != null) {
427                        for (table t : dataflow.getResultsets()) {
428                                t.setIsTarget(null);
429                                if (t.getColumns() != null) {
430                                        for (column t1 : t.getColumns()) {
431                                                t1.setIsFunction(null);
432                                        }
433                                }
434                        }
435                }
436                
437                if(dataflow!=null && dataflow.getRelationships()!=null && option.getFilterRelationTypes()!=null && !option.getFilterRelationTypes().isEmpty()) {
438                        List<relationship> relationships = new ArrayList<relationship>();
439                        for(relationship relationship: dataflow.getRelationships()) {
440                                if(option.getFilterRelationTypes().contains(relationship.getType())) {
441                                        relationships.add(relationship);
442                                }
443                        }
444                        dataflow.setRelationships(relationships);
445                }
446
447                if (option.getHandleListener() != null) {
448                        option.getHandleListener().endAnalyze(dataflow);
449                }
450
451                if (option.isOutput()) {
452                        if (option.getHandleListener() != null) {
453                                option.getHandleListener().startOutputDataFlowXML();
454                        }
455                        if (dataflow != null) {
456                                if (option.isTextFormat()) {
457                                        dataflowString = getTextOutput(dataflow);
458                                } else {
459                                        try {
460                                                dataflowString = XML2Model.saveXML(dataflow);
461                                        }catch (Exception e){
462                                                logger.error("Output dataflow to xml failed.", e);
463                                                dataflowString = null;
464                                        }
465                                }
466                        }
467                        if (option.getHandleListener() != null) {
468                                option.getHandleListener().endOutputDataFlowXML(dataflowString == null ? 0 : dataflowString.length());
469                        }
470                }
471
472                return dataflowString;
473        }
474
475        private dataflow removeDuplicateColumns(dataflow dataflow) {
476                List<table> tables = new ArrayList<table>();
477                if (dataflow.getTables() != null) {
478                        tables.addAll(dataflow.getTables());
479                }
480                if (dataflow.getViews() != null) {
481                        tables.addAll(dataflow.getViews());
482                }
483                if (dataflow.getStages() != null) {
484                        tables.addAll(dataflow.getStages());
485                }
486                if (dataflow.getDatasources() != null) {
487                        tables.addAll(dataflow.getDatasources());
488                }
489                if (dataflow.getStreams() != null) {
490                        tables.addAll(dataflow.getStreams());
491                }
492                if (dataflow.getPaths() != null) {
493                        tables.addAll(dataflow.getPaths());
494                }
495                if (dataflow.getVariables() != null) {
496                        tables.addAll(dataflow.getVariables());
497                }
498                if (dataflow.getResultsets() != null) {
499                        tables.addAll(dataflow.getResultsets());
500                }
501                for (table table : tables) {
502                        if (table.getColumns() == null) {
503                                continue;
504                        }
505                        Set<String> columnIds = new HashSet<String>();
506                        Iterator<column> iter = table.getColumns().iterator();
507                        while(iter.hasNext()) {
508                                column column = iter.next();
509                                String id = column.getId();
510                                if (columnIds.contains(id)) {
511                                        iter.remove();
512                                } else {
513                                        columnIds.add(id);
514                                }
515                        }
516                }
517                return dataflow;
518        }
519
520        public synchronized String generateDataFlow() {
521                return generateDataFlow(false);
522        }
523
524        public synchronized String generateSqlInfos() {
525                return JSON.toJSONString(sqlInfoMap);
526        }
527
528        public Map<String, List<SqlInfo>> getSqlInfos() {
529                return sqlInfoMap;
530        }
531
532        public Map getHashSQLMap() {
533                return modelManager.getHashSQLMap();
534        }
535        
536        public Map getDynamicSQLMap() {
537                return modelManager.getDynamicSQLMap();
538        }
539
540        /**
541         * @deprecated please use SqlInfoHelper.getSelectedDbObjectInfo
542         */
543        public DbObjectPosition getSelectedDbObjectInfo(Coordinate start, Coordinate end) {
544                if (start == null || end == null) {
545                        throw new IllegalArgumentException("Coordinate can't be null.");
546                }
547
548                String hashCode = start.getHashCode();
549
550                if (hashCode == null) {
551                        throw new IllegalArgumentException("Coordinate hashcode can't be null.");
552                }
553
554                int dbObjectStartLine = (int) start.getX() - 1;
555                int dbObjectStarColumn = (int) start.getY() - 1;
556                int dbObjectEndLine = (int) end.getX() - 1;
557                int dbObjectEndColumn = (int) end.getY() - 1;
558                List<SqlInfo> sqlInfoList;
559                if (hashCode.matches("\\d+")) {
560                        sqlInfoList = sqlInfoMap.getValueAtIndex(Integer.valueOf(hashCode));
561                } else {
562                        sqlInfoList = sqlInfoMap.get(hashCode);
563                }
564                for (int j = 0; j < sqlInfoList.size(); j++) {
565                        SqlInfo sqlInfo = sqlInfoList.get(j);
566                        int startLine = sqlInfo.getLineStart();
567                        int endLine = sqlInfo.getLineEnd();
568                        if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) {
569                                DbObjectPosition position = new DbObjectPosition();
570                                position.setFile(sqlInfo.getFileName());
571                                position.setFilePath(sqlInfo.getFilePath());
572                                position.setSql(sqlInfo.getSql());
573                                position.setIndex(sqlInfo.getOriginIndex());
574                                List<Pair<Integer, Integer>> positions = position.getPositions();
575                                positions.add(new Pair<Integer, Integer>(
576                                                dbObjectStartLine - startLine + sqlInfo.getOriginLineStart() + 1, dbObjectStarColumn + 1));
577                                positions.add(new Pair<Integer, Integer>(dbObjectEndLine - startLine + sqlInfo.getOriginLineStart() + 1,
578                                                dbObjectEndColumn + 1));
579                                return position;
580                        }
581                }
582                return null;
583        }
584
585        public static dataflow mergeTables(dataflow dataflow, Long startId) {
586                return mergeTables(dataflow, startId, new Option());
587        }
588
589        public static dataflow mergeTables(dataflow dataflow, Long startId, Option option) {
590                List<table> tableCopy = new ArrayList<table>();
591                List<table> viewCopy = new ArrayList<table>();
592                List<table> databaseCopy = new ArrayList<table>();
593                List<table> schemaCopy = new ArrayList<table>();
594                List<table> stageCopy = new ArrayList<table>();
595                List<table> dataSourceCopy = new ArrayList<table>();
596                List<table> streamCopy = new ArrayList<table>();
597                List<table> fileCopy = new ArrayList<table>();
598                List<table> variableCopy = new ArrayList<table>();
599                List<table> cursorCopy = new ArrayList<table>();
600                List<table> resultSetCopy = new ArrayList<table>();
601                if (dataflow.getTables() != null) {
602                        tableCopy.addAll(dataflow.getTables());
603                }
604                dataflow.setTables(tableCopy);
605                if (dataflow.getViews() != null) {
606                        viewCopy.addAll(dataflow.getViews());
607                }
608                dataflow.setViews(viewCopy);
609                if (dataflow.getDatabases() != null) {
610                        databaseCopy.addAll(dataflow.getDatabases());
611                }
612                dataflow.setDatabases(databaseCopy);
613                if (dataflow.getSchemas() != null) {
614                        schemaCopy.addAll(dataflow.getSchemas());
615                }
616                dataflow.setSchemas(schemaCopy);
617                if (dataflow.getStages() != null) {
618                        stageCopy.addAll(dataflow.getStages());
619                }
620                dataflow.setStages(stageCopy);
621                if (dataflow.getDatasources() != null) {
622                        dataSourceCopy.addAll(dataflow.getDatasources());
623                }
624                dataflow.setDatasources(dataSourceCopy);
625                if (dataflow.getStreams() != null) {
626                        streamCopy.addAll(dataflow.getStreams());
627                }
628                dataflow.setStreams(streamCopy);
629                if (dataflow.getPaths() != null) {
630                        fileCopy.addAll(dataflow.getPaths());
631                }
632                dataflow.setPaths(fileCopy);
633                if (dataflow.getVariables() != null) {
634                        variableCopy.addAll(dataflow.getVariables());
635                }
636                dataflow.setVariables(variableCopy);
637                if (dataflow.getResultsets() != null) {
638                        resultSetCopy.addAll(dataflow.getResultsets());
639                }
640                dataflow.setResultsets(resultSetCopy);
641
642                Map<String, List<table>> tableMap = new HashMap<String, List<table>>();
643                Map<String, String> tableTypeMap = new HashMap<String, String>();
644                Map<String, TMssqlCreateType> mssqlTypeMap = new HashMap<String, TMssqlCreateType>();
645                Map<String, String> tableIdMap = new HashMap<String, String>();
646
647                Map<String, List<column>> columnMap = new HashMap<String, List<column>>();
648                Map<String, Set<String>> tableColumnMap = new HashMap<String, Set<String>>();
649                Map<String, String> columnIdMap = new HashMap<String, String>();
650                Map<String, column> columnMergeIdMap = new HashMap<String, column>();
651
652                List<table> tables = new ArrayList<table>();
653                tables.addAll(dataflow.getTables());
654                tables.addAll(dataflow.getViews());
655                tables.addAll(dataflow.getDatabases());
656                tables.addAll(dataflow.getSchemas());
657                tables.addAll(dataflow.getStages());
658                tables.addAll(dataflow.getDatasources());
659                tables.addAll(dataflow.getStreams());
660                tables.addAll(dataflow.getPaths());
661                tables.addAll(dataflow.getResultsets());
662                tables.addAll(dataflow.getVariables());
663                
664                Set<String> columnIds = new HashSet<String>();
665
666                for (table table : tables) {
667                        String qualifiedTableName = DlineageUtil.getQualifiedTableName(table);
668                        String tableFullName = DlineageUtil.getIdentifierNormalTableName(qualifiedTableName);
669
670                        if (!tableMap.containsKey(tableFullName)) {
671                                tableMap.put(tableFullName, new ArrayList<table>());
672                        }
673
674                        tableMap.get(tableFullName).add(table);
675
676                        if (!tableTypeMap.containsKey(tableFullName)) {
677                                tableTypeMap.put(tableFullName, table.getType());
678                        } else if ("view".equals(table.getSubType())) {
679                                tableTypeMap.put(tableFullName, table.getType());
680                        } else if ("database".equals(table.getSubType())) {
681                                tableTypeMap.put(tableFullName, table.getType());
682                        } else if ("schema".equals(table.getSubType())) {
683                                tableTypeMap.put(tableFullName, table.getType());
684                        } else if ("stage".equals(table.getSubType())) {
685                                tableTypeMap.put(tableFullName, table.getType());
686                        } else if ("sequence".equals(table.getSubType())) {
687                                tableTypeMap.put(tableFullName, table.getType());
688                        } else if ("datasource".equals(table.getSubType())) {
689                                tableTypeMap.put(tableFullName, table.getType());
690                        } else if ("stream".equals(table.getSubType())) {
691                                tableTypeMap.put(tableFullName, table.getType());
692                        } else if ("file".equals(table.getSubType())) {
693                                tableTypeMap.put(tableFullName, table.getType());
694                        } else if ("table".equals(tableTypeMap.get(tableFullName))) {
695                                tableTypeMap.put(tableFullName, table.getType());
696                        } else if ("variable".equals(tableTypeMap.get(tableFullName))) {
697                                tableTypeMap.put(tableFullName, table.getType());
698                        }
699
700                        if (table.getColumns() != null) {
701                                if (!tableColumnMap.containsKey(tableFullName)) {
702                                        tableColumnMap.put(tableFullName, new LinkedHashSet<String>());
703                                }
704                                for (column column : table.getColumns()) {
705                                        String columnFullName = tableFullName + "."
706                                                        + (column.getQualifiedTable() != null
707                                                                        ? (DlineageUtil.getIdentifierNormalTableName(column.getQualifiedTable()) + ".")
708                                                                        : "")
709                                                        + ("false".equals(table.getIsTarget()) ? DlineageUtil.normalizeColumnName(column.getName())
710                                                                        : DlineageUtil.getIdentifierNormalColumnName(column.getName()));
711
712                                        if (!columnMap.containsKey(columnFullName)) {
713                                                columnMap.put(columnFullName, new ArrayList<column>());
714                                                tableColumnMap.get(tableFullName).add(columnFullName);
715                                        }
716
717                                        columnMap.get(columnFullName).add(column);
718                                        columnIds.add(column.getId());
719                                }
720                        }
721                }
722
723                Iterator<String> tableNameIter = tableMap.keySet().iterator();
724                while (tableNameIter.hasNext()) {
725                        String tableName = tableNameIter.next();
726                        List<table> tableList = tableMap.get(tableName);
727                        table table;
728                        if (tableList.size() > 1) {
729                                table standardTable = tableList.get(0);
730                                // Function允许重名,不做合并处理
731                                if (standardTable.isFunction()) {
732                                        continue;
733                                }
734                                
735                                // Variable允许重名,不做合并处理
736                                if (standardTable.isVariable()) {
737                                        continue;
738                                }
739                                
740                                // 临时表不做合并处理
741                                if(SQLUtil.isTempTable(standardTable)) {
742                                        continue;
743                                }
744
745                                String type = tableTypeMap.get(tableName);
746                                table = new table();
747                                table.setId(String.valueOf(++startId));
748                                table.setServer(standardTable.getServer());
749                                table.setDatabase(standardTable.getDatabase());
750                                table.setSchema(standardTable.getSchema());
751                                table.setName(standardTable.getName());
752                                table.setDisplayName(standardTable.getDisplayName());
753                                table.setParent(standardTable.getParent());
754                                table.setMore(standardTable.getMore());
755                                table.setColumns(new ArrayList<column>());
756                                table.setSubType(standardTable.getSubType());
757                                Set<String> processIds = new LinkedHashSet<String>();
758                                for (int k = 0; k < tableList.size(); k++) {
759                                        if (tableList.get(k).getProcessIds() != null) {
760                                                processIds.addAll(tableList.get(k).getProcessIds());
761                                        }
762                                }
763                                if (!processIds.isEmpty()) {
764                                        table.setProcessIds(new ArrayList<String>(processIds));
765                                }
766                                Set<String> alias = new LinkedHashSet<String>();
767                                for (int k = 0; k < tableList.size(); k++) {
768                                        if (tableList.get(k).getAlias() != null) {
769                                                alias.addAll(Arrays.asList(tableList.get(k).getAlias().split("\\s*,\\s*")));
770                                        }
771                                }
772                                if (!alias.isEmpty()) {
773                                        String aliasString = Arrays.toString(alias.toArray(new String[0]));
774                                        table.setAlias(aliasString.substring(1, aliasString.length() - 1));
775                                }
776                                table.setType(type);
777                                for (table item : tableList) {
778                                        if (!SQLUtil.isEmpty(table.getCoordinate()) && !SQLUtil.isEmpty(item.getCoordinate())) {
779                                                if (table.getCoordinate().indexOf(item.getCoordinate()) == -1) {
780                                                        table.appendCoordinate(item.getCoordinate());
781                                                }
782                                        } else if (!SQLUtil.isEmpty(item.getCoordinate())) {
783                                                table.setCoordinate(item.getCoordinate());
784                                        }
785
786                                        if (item.getStarStmt() != null) {
787                                                table.setStarStmt(item.getStarStmt());
788                                        }
789
790                                        tableIdMap.put(item.getId(), table.getId());
791
792                                        if (item.isView()) {
793                                                dataflow.getViews().remove(item);
794                                        } else if (item.isDatabaseType()) {
795                                                dataflow.getDatabases().remove(item);
796                                        } else if (item.isSchemaType()) {
797                                                dataflow.getSchemas().remove(item);
798                                        } else if (item.isStage()) {
799                                                dataflow.getStages().remove(item);
800                                        } else if (item.isDataSource()) {
801                                                dataflow.getDatasources().remove(item);
802                                        } else if (item.isStream()) {
803                                                dataflow.getStreams().remove(item);
804                                        } else if (item.isFile()) {
805                                                dataflow.getPaths().remove(item);
806                                        } else if (item.isVariable()) {
807                                                dataflow.getVariables().remove(item);
808                                        } else if (item.isTable()) {
809                                                dataflow.getTables().remove(item);
810                                        } else if (item.isResultSet()) {
811                                                dataflow.getResultsets().remove(item);
812                                        }
813                                }
814
815                                if (table.isView()) {
816                                        dataflow.getViews().add(table);
817                                } else if (table.isDatabaseType()) {
818                                        dataflow.getDatabases().add(table);
819                                } else if (table.isSchemaType()) {
820                                        dataflow.getSchemas().add(table);
821                                } else if (table.isStage()) {
822                                        dataflow.getStages().add(table);
823                                } else if (table.isDataSource()) {
824                                        dataflow.getDatasources().add(table);
825                                } else if (table.isStream()) {
826                                        dataflow.getStreams().add(table);
827                                } else if (table.isFile()) {
828                                        dataflow.getPaths().add(table);
829                                } else if (table.isVariable()) {
830                                        dataflow.getVariables().add(table);
831                                } else if (table.isResultSet()) {
832                                        dataflow.getResultsets().add(table);
833                                } else {
834                                        dataflow.getTables().add(table);
835                                }
836                        } else {
837                                table = tableList.get(0);
838                                if(Boolean.TRUE.toString().equals(table.getIsDetermined())){
839                                        continue;
840                                }
841                                
842                                if (option.isIgnoreUnusedSynonym() && SubType.synonym.name().equals(table.getSubType())) {
843                                        dataflow.getTables().remove(table);
844                                        tableColumnMap.get(tableName).clear();
845                                        continue;
846                                }
847                        }
848
849                        Set<String> columns = tableColumnMap.get(tableName);
850                        Iterator<String> columnIter = columns.iterator();
851                        List<column> mergeColumns = new ArrayList<column>();
852                        while (columnIter.hasNext()) {
853                                String columnName = columnIter.next();
854                                List<column> columnList = columnMap.get(columnName);
855                                List<column> functions = new ArrayList<column>();
856                                for (column t : columnList) {
857                                        if (Boolean.TRUE.toString().equals(t.getIsFunction())) {
858                                                functions.add(t);
859                                        }
860                                }
861                                if (functions != null && !functions.isEmpty()) {
862                                        for (column function : functions) {
863                                                mergeColumns.add(function);
864                                                columnIdMap.put(function.getId(), function.getId());
865                                                columnMergeIdMap.put(function.getId(), function);
866                                        }
867
868                                        columnList.removeAll(functions);
869                                }
870                                if (!columnList.isEmpty()) {
871                                        column firstColumn = columnList.iterator().next();
872                                        if (columnList.size() > 1) {
873                                                column mergeColumn = new column();
874                                                mergeColumn.setId(String.valueOf(++startId));
875                                                mergeColumn.setName(firstColumn.getName());
876                                                mergeColumn.setDisplayName(firstColumn.getDisplayName());
877                                                mergeColumn.setSource(firstColumn.getSource());
878                                                mergeColumn.setQualifiedTable(firstColumn.getQualifiedTable());
879                                                mergeColumn.setDataType(firstColumn.getDataType());
880                                                mergeColumn.setForeignKey(firstColumn.isForeignKey());
881                                                mergeColumn.setPrimaryKey(firstColumn.isPrimaryKey());
882                                                mergeColumn.setUnqiueKey(firstColumn.isUnqiueKey());
883                                                mergeColumn.setIndexKey(firstColumn.isIndexKey());
884                                                mergeColumns.add(mergeColumn);
885                                                for (column item : columnList) {
886                                                        mergeColumn.appendCoordinate(item.getCoordinate());
887                                                        columnIdMap.put(item.getId(), mergeColumn.getId());
888                                                }
889                                                columnMergeIdMap.put(mergeColumn.getId(), mergeColumn);
890                                                columnIds.add(mergeColumn.getId());
891                                        } else {
892                                                mergeColumns.add(firstColumn);
893                                                columnIdMap.put(firstColumn.getId(), firstColumn.getId());
894                                                columnMergeIdMap.put(firstColumn.getId(), firstColumn);
895                                        }
896                                }
897                        }
898                        table.setColumns(mergeColumns);
899                }
900
901                if (dataflow.getRelationships() != null) {
902                        Map<String, relationship> mergeRelations = new LinkedHashMap<String, relationship>();
903                        for (int i = 0; i < dataflow.getRelationships().size(); i++) {
904                                relationship relation = dataflow.getRelationships().get(i);
905                                
906                                if("crud".equals(relation.getType()) && option.getAnalyzeMode() == AnalyzeMode.crud) {
907                                        String jsonString = JSON.toJSONString(relation, true);
908                                        String key = SHA256.getMd5(jsonString);
909                                        if (!mergeRelations.containsKey(key)) {
910                                                mergeRelations.put(key, relation);
911                                        }
912                                        continue;
913                                }
914                                
915                                targetColumn target = relation.getTarget();
916                                if ("call".equals(relation.getType())) {
917                                        target = relation.getCaller();
918                                }
919                                if (target != null && tableIdMap.containsKey(target.getParent_id())) {
920                                        target.setParent_id(tableIdMap.get(target.getParent_id()));
921                                }
922
923                                if (columnIdMap.containsKey(target.getId())) {
924                                        target.setId(columnIdMap.get(target.getId()));
925                                        target.setCoordinate(columnMergeIdMap.get(target.getId()).getCoordinate());
926                                }
927                                else if(option.isIgnoreUnusedSynonym() && EffectType.synonym.name().equals(relation.getEffectType())){
928                                        continue;
929                                }
930                                
931                                if (!"call".equals(relation.getType()) && !columnIds.contains(target.getId())) {
932                                        continue;
933                                }
934
935                                List<sourceColumn> sources = relation.getSources();
936                                if ("call".equals(relation.getType())) {
937                                        sources = relation.getCallees();
938                                }
939                                Set<sourceColumn> sourceSet = new LinkedHashSet<sourceColumn>();
940                                if (sources != null) {
941                                        for (sourceColumn source : sources) {
942                                                if (!"call".equals(relation.getType()) && !columnIds.contains(source.getId())) {
943                                                        continue;
944                                                }
945                                                if (tableIdMap.containsKey(source.getParent_id())) {
946                                                        source.setParent_id(tableIdMap.get(source.getParent_id()));
947                                                }
948                                                if (tableIdMap.containsKey(source.getSource_id())) {
949                                                        source.setSource_id(tableIdMap.get(source.getSource_id()));
950                                                }
951                                                if (columnIdMap.containsKey(source.getId())) {
952                                                        source.setId(columnIdMap.get(source.getId()));
953                                                        source.setCoordinate(columnMergeIdMap.get(source.getId()).getCoordinate());
954                                                }
955                                        }
956
957                                        sourceSet.addAll(sources);
958                                        if ("call".equals(relation.getType())) {
959                                                relation.setCallees(new ArrayList<sourceColumn>(sourceSet));
960                                        } else {
961                                                relation.setSources(new ArrayList<sourceColumn>(sourceSet));
962                                        }
963                                }
964
965                                String jsonString = JSON.toJSONString(relation, true);
966                                String key = SHA256.getMd5(jsonString);
967                                if (!mergeRelations.containsKey(key)) {
968                                        mergeRelations.put(key, relation);
969                                }
970                        }
971
972                        dataflow.setRelationships(new ArrayList<relationship>(mergeRelations.values()));
973                }
974
975                tableMap.clear();
976                tableTypeMap.clear();
977                tableIdMap.clear();
978                columnMap.clear();
979                tableColumnMap.clear();
980                columnIdMap.clear();
981                columnMergeIdMap.clear();
982                tables.clear();
983                return dataflow;
984        }
985
986        public synchronized dataflow getDataFlow() {
987                if (dataflow != null) {
988                        return dataflow;
989                } else if (dataflowString != null) {
990                        return XML2Model.loadXML(dataflow.class, dataflowString);
991                }
992                return null;
993        }
994
995        List<ErrorInfo> metadataErrors = new ArrayList<>();
996        
997        private synchronized dataflow analyzeSqlScript() {
998                init();
999
1000                try {
1001                        dataflow dataflow = new dataflow();
1002                        
1003                        if (sqlInfos != null) {
1004                                if (option.getHandleListener() != null) {
1005                                        if (sqlInfos.length == 1) {
1006                                                option.getHandleListener().startAnalyze(null, sqlInfos[0].getSql().length(), false);
1007                                        } else {
1008                                                option.getHandleListener().startAnalyze(null, sqlInfos.length, true);
1009                                        }
1010                                }
1011
1012                                if (sqlenv == null) {
1013                                        if (option.getHandleListener() != null) {
1014                                                option.getHandleListener().startParseSQLEnv();
1015                                        }
1016                                        TSQLEnv[] sqlenvs = new SQLEnvParser(option.getDefaultServer(), option.getDefaultDatabase(),
1017                                                        option.getDefaultSchema()).parseSQLEnv(option.getVendor(), sqlInfos);
1018                                        if (sqlenvs != null && sqlenvs.length > 0) {
1019                                                sqlenv = sqlenvs[0];
1020                                        }
1021                                        if (option.getHandleListener() != null) {
1022                                                option.getHandleListener().endParseSQLEnv();
1023                                        }
1024                                }
1025                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
1026                                Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap = new LinkedHashMap<String, Pair3<StringBuilder, AtomicInteger, String>>();
1027                                for (int i = 0; i < sqlInfos.length; i++) {
1028                                        SqlInfo sqlInfo = sqlInfos[i];
1029                                        if (sqlInfo == null) {
1030                                                sqlInfoMap.put(String.valueOf(i), new ArrayList<SqlInfo>());
1031                                                continue;
1032                                        }
1033                                        String sql = sqlInfo.getSql();
1034                                        if (SQLUtil.isEmpty(sql) && sqlInfo.getFileName() != null
1035                                                        && new File(sqlInfo.getFileName()).exists()) {
1036                                                sql = SQLUtil.getFileContent(sqlInfo.getFileName());
1037                                        }
1038                                        if (SQLUtil.isEmpty(sql) && sqlInfo.getFilePath() != null
1039                                                        && new File(sqlInfo.getFilePath()).exists()) {
1040                                                sql = SQLUtil.getFileContent(sqlInfo.getFilePath());
1041                                        }
1042                                        String sqlTrim = null;
1043                                        if (sql != null) {
1044                                                sqlTrim = sql.substring(0, Math.min(sql.length(), 512)).trim();
1045                                        }
1046                                        if(sql!=null && sqlTrim.startsWith("<") && sqlTrim.indexOf("<dlineage")!=-1){
1047                                                dataflow temp = XML2Model.loadXML(dataflow.class, sql);
1048                                                if(sqlInfos.length == 1){
1049                                                        dataflow = temp;
1050                                                }
1051                                                else {
1052                                                        if (temp.getTables() != null) {
1053                                                                dataflow.getTables().addAll(temp.getTables());
1054                                                        }
1055                                                        if (temp.getViews() != null) {
1056                                                                dataflow.getViews().addAll(temp.getViews());
1057                                                        }
1058                                                        if (temp.getResultsets() != null) {
1059                                                                dataflow.getResultsets().addAll(temp.getResultsets());
1060                                                        }
1061                                                        if (temp.getRelationships() != null) {
1062                                                                dataflow.getRelationships().addAll(temp.getRelationships());
1063                                                        }
1064                                                        if (temp.getErrors() != null) {
1065                                                                dataflow.getErrors().addAll(temp.getErrors());
1066                                                        }
1067                                                }
1068                                        }
1069                                        else if (sql != null && sqlTrim.startsWith("{")) {
1070                                                EDbVendor vendor = SQLUtil.isEmpty(sqlInfo.getDbVendor()) ? option.getVendor()
1071                                                                : EDbVendor.valueOf(sqlInfo.getDbVendor());
1072                                                TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(),
1073                                                                option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql);
1074                                                if (sqlenvs != null && sqlenvs.length > 0) {
1075                                                        if (sqlenv == null) {
1076                                                                sqlenv = sqlenvs[0];
1077                                                        } else {
1078                                                                sqlenv = SQLEnvParser.mergeSQLEnv(Arrays.asList(sqlenv, sqlenvs[0]));
1079                                                        }
1080                                                }
1081                                                if (sqlenv != null) {
1082                                                        if (MetadataReader.isGrabit(sql) || MetadataReader.isSqlflow(sql)) {
1083                                                                String hash = SHA256.getMd5(sql);
1084                                                                String fileHash = SHA256.getMd5(hash);
1085                                                                if (!sqlInfoMap.containsKey(fileHash)) {
1086                                                                        sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1087                                                                        sqlInfoMap.get(fileHash).add(sqlInfo);
1088                                                                }
1089                                                                ModelBindingManager.setGlobalHash(fileHash);
1090                                                                dataflow temp = null;
1091
1092                                                                if (MetadataReader.isGrabit(sql)) {
1093                                                                        temp = new GrabitMetadataAnalyzer().analyzeMetadata(option.getVendor(), sql);
1094                                                                } else {
1095                                                                        temp = new SqlflowMetadataAnalyzer(sqlenv).analyzeMetadata(option.getVendor(), sql);
1096                                                                }
1097//                                                              if (temp.getPackages() != null) {
1098//                                                                      dataflow.getPackages().addAll(temp.getPackages());
1099//                                                              }
1100//                                                              if (temp.getProcedures() != null) {
1101//                                                                      dataflow.getProcedures().addAll(temp.getProcedures());
1102//                                                              }
1103                                                                if (temp.getTables() != null) {
1104                                                                        dataflow.getTables().addAll(temp.getTables());
1105                                                                }
1106                                                                if (temp.getViews() != null) {
1107                                                                        dataflow.getViews().addAll(temp.getViews());
1108                                                                }
1109                                                                if (temp.getResultsets() != null) {
1110                                                                        dataflow.getResultsets().addAll(temp.getResultsets());
1111                                                                }
1112                                                                if (temp.getRelationships() != null) {
1113                                                                        dataflow.getRelationships().addAll(temp.getRelationships());
1114                                                                }
1115                                                                if (temp.getErrors() != null) {
1116                                                                        dataflow.getErrors().addAll(temp.getErrors());
1117                                                                }
1118                                                                if (sql.indexOf("createdBy") != -1) {
1119                                                                        if (sql.toLowerCase().indexOf("sqldep") != -1
1120                                                                                        || sql.toLowerCase().indexOf("grabit") != -1) {
1121                                                                                Map jsonObject = (Map) JSON.parseObject(sql);
1122                                                                                List<Map> queries = (List<Map>) jsonObject.get("queries");
1123                                                                                if (queries != null) {
1124                                                                                        for (int j = 0; j < queries.size(); j++) {
1125                                                                                                Map queryObject = queries.get(j);
1126                                                                                                appendSqlInfo(databaseMap, j, sqlInfo, queryObject);
1127                                                                                        }
1128                                                                                }
1129                                                                        } else if (sql.toLowerCase().indexOf("sqlflow") != -1) {
1130                                                                                Map sqlflow = (Map) JSON.parseObject(sql);
1131                                                                                List<Map> servers = (List<Map>) sqlflow.get("servers");
1132                                                                                if (servers != null) {
1133                                                                                        for (Map serverObject : servers) {
1134                                                                                                List<Map> queries = (List<Map>) serverObject.get("queries");
1135                                                                                                if (queries != null) {
1136                                                                                                        for (int j = 0; j < queries.size(); j++) {
1137                                                                                                                Map queryObject = queries.get(j);
1138                                                                                                                appendSqlInfo(databaseMap, j, sqlInfo, queryObject);
1139                                                                                                        }
1140                                                                                                }
1141                                                                                        }
1142                                                                                }
1143                                                                                List<Map> errorMessages =  (List<Map>) sqlflow.get("errorMessages");
1144                                                                                if(errorMessages!=null && !errorMessages.isEmpty()) {
1145                                                                                        for(Map error: errorMessages){
1146                                                                                                ErrorInfo errorInfo = new ErrorInfo();
1147                                                                                                errorInfo.setErrorType(ErrorInfo.METADATA_ERROR);
1148                                                                                                errorInfo.setErrorMessage((String)error.get("errorMessage"));
1149                                                                                                errorInfo.setFileName(sqlInfo.getFileName());
1150                                                                                                errorInfo.setFilePath(sqlInfo.getFilePath());
1151                                                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L,
1152                                                                                                                ModelBindingManager.getGlobalHash()));
1153                                                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L,
1154                                                                                                                ModelBindingManager.getGlobalHash()));
1155                                                                                                errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L));
1156                                                                                                errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L));
1157                                                                                                metadataErrors.add(errorInfo);
1158                                                                                        }
1159                                                                                }
1160                                                                        }
1161                                                                }
1162                                                        } else {
1163                                                                Map queryObject = (Map) JSON.parseObject(sql);
1164                                                                appendSqlInfo(databaseMap, i, sqlInfo, queryObject);
1165                                                        }
1166                                                } else {
1167                                                        Map queryObject = (Map) JSON.parseObject(sql);
1168                                                        appendSqlInfo(databaseMap, i, sqlInfo, queryObject);
1169                                                }
1170                                        } else {
1171                                                ModelBindingManager.removeGlobalDatabase();
1172                                                ModelBindingManager.removeGlobalSchema();
1173                                                ModelBindingManager.removeGlobalHash();
1174
1175                                                String content = sql;
1176
1177                                                if (content == null) {
1178                                                        continue;
1179                                                }
1180
1181                                                String delimiterChar = String.valueOf(sqlparser.getDelimiterChar());
1182
1183                                                if (sqlInfos.length > 1) {
1184                                                        String endTrim = SQLUtil.endTrim(content);
1185                                                        if (endTrim.endsWith(delimiterChar) || endTrim.endsWith(";")) {
1186                                                                content += "\n";
1187                                                        } else if (option.getVendor() == EDbVendor.dbvredshift
1188                                                                        || option.getVendor() == EDbVendor.dbvgaussdb
1189                                                                        || option.getVendor() == EDbVendor.dbvpostgresql
1190                                                                        || option.getVendor() == EDbVendor.dbvmysql
1191                                                                        || option.getVendor() == EDbVendor.dbvteradata) {
1192                                                                content += ("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n");
1193                                                        } else {
1194                                                                content = endTrim + ";" + "\n";
1195                                                        }
1196                                                }
1197
1198                                                sqlInfo.setSql(content);
1199
1200                                                if (MetadataReader.isMetadata(content)) {
1201                                                        String hash = SHA256.getMd5(content);
1202                                                        ModelBindingManager.setGlobalHash(hash);
1203                                                        dataflow temp = new SQLDepMetadataAnalyzer().analyzeMetadata(option.getVendor(), content);
1204                                                        if (temp.getProcedures() != null) {
1205                                                                dataflow.getProcedures().addAll(temp.getProcedures());
1206                                                        }
1207                                                        if (temp.getTables() != null) {
1208                                                                dataflow.getTables().addAll(temp.getTables());
1209                                                        }
1210                                                        if (temp.getViews() != null) {
1211                                                                dataflow.getViews().addAll(temp.getViews());
1212                                                        }
1213                                                        if (temp.getResultsets() != null) {
1214                                                                dataflow.getResultsets().addAll(temp.getResultsets());
1215                                                        }
1216                                                        if (temp.getRelationships() != null) {
1217                                                                dataflow.getRelationships().addAll(temp.getRelationships());
1218                                                        }
1219                                                        if (temp.getErrors() != null) {
1220                                                                dataflow.getErrors().addAll(temp.getErrors());
1221                                                        }
1222                                                        String fileHash = SHA256.getMd5(hash);
1223                                                        if (!sqlInfoMap.containsKey(fileHash)) {
1224                                                                sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1225                                                                sqlInfoMap.get(fileHash).add(sqlInfo);
1226                                                        }
1227                                                } else {
1228                                                        String sqlHash = SHA256.getMd5(content);
1229                                                        String fileHash = SHA256.getMd5(sqlHash);
1230                                                        if (!sqlInfoMap.containsKey(fileHash)) {
1231                                                                sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1232                                                        }
1233
1234                                                        String database = TSQLEnv.DEFAULT_DB_NAME;
1235                                                        String schema = TSQLEnv.DEFAULT_SCHEMA_NAME;
1236                                                        if (sqlenv != null) {
1237                                                                database = sqlenv.getDefaultCatalogName();
1238                                                                if (database == null) {
1239                                                                        database = TSQLEnv.DEFAULT_DB_NAME;
1240                                                                }
1241                                                                schema = sqlenv.getDefaultSchemaName();
1242                                                                if (schema == null) {
1243                                                                        schema = TSQLEnv.DEFAULT_SCHEMA_NAME;
1244                                                                }
1245                                                        }
1246
1247                                                        boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor());
1248                                                        boolean supportSchema = TSQLEnv.supportSchema(option.getVendor());
1249                                                        StringBuilder builder = new StringBuilder();
1250                                                        if (supportCatalog) {
1251                                                                builder.append(database);
1252                                                        }
1253                                                        if (supportSchema) {
1254                                                                if (builder.length() > 0) {
1255                                                                        builder.append(".");
1256                                                                }
1257                                                                builder.append(schema);
1258                                                        }
1259                                                        String group = builder.toString();
1260                                                        SqlInfo sqlInfoItem = new SqlInfo();
1261                                                        sqlInfoItem.setFileName(sqlInfo.getFileName());
1262                                                        sqlInfoItem.setFilePath(sqlInfo.getFilePath());
1263                                                        sqlInfoItem.setSql(sqlInfo.getSql());
1264                                                        sqlInfoItem.setOriginIndex(0);
1265                                                        sqlInfoItem.setOriginLineStart(0);
1266                                                        int lineEnd = sqlInfo.getSql().split("\n").length - 1;
1267                                                        sqlInfoItem.setOriginLineEnd(lineEnd);
1268                                                        sqlInfoItem.setIndex(0);
1269                                                        sqlInfoItem.setLineStart(0);
1270                                                        sqlInfoItem.setLineEnd(lineEnd);
1271                                                        sqlInfoItem.setHash(SHA256.getMd5(sqlHash));
1272                                                        sqlInfoItem.setGroup(group);
1273                                                        sqlInfoMap.get(fileHash).add(sqlInfoItem);
1274                                                        if (!databaseMap.containsKey(sqlHash)) {
1275                                                                databaseMap.put(sqlHash, new Pair3<StringBuilder, AtomicInteger, String>(
1276                                                                                new StringBuilder(), new AtomicInteger(), group));
1277                                                        }
1278                                                        databaseMap.get(sqlHash).first.append(sqlInfoItem.getSql());
1279                                                        databaseMap.get(sqlHash).second.incrementAndGet();
1280                                                }
1281                                        }
1282                                }
1283
1284                                boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor());
1285                                boolean supportSchema = TSQLEnv.supportSchema(option.getVendor());
1286
1287                                Iterator<String> schemaIter = databaseMap.keySet().iterator();
1288                                while (schemaIter.hasNext()) {
1289                                        if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
1290                                                break;
1291                                        }
1292                                        String key = schemaIter.next();
1293                                        String group = databaseMap.get(key).third;
1294                                        String[] split = SQLUtil.parseNames(group).toArray(new String[0]);
1295
1296                                        ModelBindingManager.removeGlobalDatabase();
1297                                        ModelBindingManager.removeGlobalSchema();
1298                                        ModelBindingManager.removeGlobalSQLEnv();
1299                                        ModelBindingManager.removeGlobalHash();
1300
1301                                        String defaultDatabase = null;
1302                                        String defaultSchema = null;
1303                                        if(sqlenv!=null){
1304                                                defaultDatabase = sqlenv.getDefaultCatalogName();
1305                                                defaultSchema = sqlenv.getDefaultSchemaName();
1306                                        }
1307                                        if (supportCatalog && supportSchema) {
1308                                                if (split.length >= 2) {
1309                                                        if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 2])) {
1310                                                                ModelBindingManager.setGlobalDatabase(split[split.length - 2]);
1311                                                                sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase());
1312                                                        }
1313                                                }
1314                                                if (split.length >= 1) {
1315                                                        if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) {
1316                                                                ModelBindingManager.setGlobalSchema(split[split.length - 1]);
1317                                                                sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema());
1318                                                        }
1319                                                }
1320                                        } else if (supportCatalog) {
1321                                                if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 1])) {
1322                                                        ModelBindingManager.setGlobalDatabase(split[split.length - 1]);
1323                                                        sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase());
1324                                                }
1325                                        } else if (supportSchema) {
1326                                                if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) {
1327                                                        ModelBindingManager.setGlobalSchema(split[split.length - 1]);
1328                                                        sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema());
1329                                                }
1330                                        }
1331                                        if (option.getHandleListener() != null) {
1332                                                option.getHandleListener().startParse(null, databaseMap.get(key).first.toString());
1333                                        }
1334
1335                                        if (sqlenv == null) {
1336                                                sqlenv = new TSQLEnv(option.getVendor()) {
1337
1338                                                        @Override
1339                                                        public void initSQLEnv() {
1340                                                                // TODO Auto-generated method stub
1341
1342                                                        }
1343                                                };
1344                                        }
1345                                        ModelBindingManager.setGlobalSQLEnv(sqlenv);
1346                                        sqlparser.sqltext = databaseMap.get(key).first.toString();
1347                                        ModelBindingManager.setGlobalHash(SHA256.getMd5(key));
1348                                        analyzeAndOutputResult(sqlparser);
1349                                        if(sqlenv!=null){
1350                                                sqlenv.setDefaultCatalogName(defaultDatabase);
1351                                                sqlenv.setDefaultSchemaName(defaultSchema);
1352                                        }
1353                                }
1354
1355                                appendProcesses(dataflow);
1356                                appendOraclePackages(dataflow);
1357                                appendProcedures(dataflow);
1358                                appendTables(dataflow);
1359                                appendViews(dataflow);
1360                                appendResultSets(dataflow);
1361                                appendRelations(dataflow);
1362                                appendErrors(dataflow);
1363                        }
1364
1365                        dataflow = handleDataflowExecProcedure(dataflow);
1366
1367                        if (dataflow != null && option.getAnalyzeMode() != AnalyzeMode.crud) {
1368                                if (!isShowJoin()) {
1369                                        dataflow = mergeTables(dataflow, modelManager.TABLE_COLUMN_ID, option);
1370                                } else {
1371                                        dataflow = removeDuplicateColumns(dataflow);
1372                                }
1373                        }
1374
1375                        if (dataflow != null && option.isNormalizeOutput()) {
1376                                dataflow = getNormalizeDataflow(dataflow);
1377                        }
1378
1379                        if (dataflow != null && option.isIgnoreCoordinate()) {
1380                                dataflow = filterDataflowCoordinate(dataflow);
1381                        }
1382                        
1383                        if (option.isSimpleOutput() || option.isIgnoreRecordSet()) {
1384                                List<String> showTypes = new ArrayList<>();
1385                                if(option.getSimpleShowRelationTypes()!=null) {
1386                                        showTypes.addAll(option.getSimpleShowRelationTypes());
1387                                }
1388                                if(showTypes.isEmpty()) {
1389                                        showTypes.add("fdd");
1390                                }
1391                                if(option.isShowCallRelation()) {
1392                                        showTypes.add("call");
1393                                }
1394                                if(option.isShowERDiagram()) {
1395                                        showTypes.add("er");
1396                                }
1397                                dataflow simpleDataflow = getSimpleDataflow(dataflow, option.isSimpleOutput(), showTypes);
1398                                if (simpleDataflow.getResultsets() != null) {
1399                                        for (table t : simpleDataflow.getResultsets()) {
1400                                                t.setIsTarget(null);
1401                                        }
1402                                }
1403                                return simpleDataflow;
1404                        } else {
1405                                return dataflow;
1406                        }
1407                        
1408                } catch (Exception e) {
1409                        logger.error("analyze sql failed.", e);
1410                        ErrorInfo errorInfo = new ErrorInfo();
1411                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
1412                        if (e.getMessage() == null) {
1413                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
1414                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
1415                                } else {
1416                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
1417                                }
1418                        } else {
1419                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
1420                        }
1421                        errorInfo.fillInfo(this);
1422                        errorInfos.add(errorInfo);
1423                }
1424
1425                modelManager.reset();
1426                return null;
1427        }
1428
1429        private dataflow handleDataflowExecProcedure(dataflow dataflow) {
1430                Set<String> procedures = new HashSet<String>();
1431                for (procedure procedure : dataflow.getProcedures()) {
1432                        procedures.add(DlineageUtil.getIdentifierNormalTableName(procedure.getName()));
1433                }
1434                List<table> removeResultSets = new ArrayList<table>();
1435                
1436                Map<String, table> allMap = new HashMap<String, table>();
1437                
1438                if (dataflow.getResultsets() != null) {
1439                        for (table t : dataflow.getResultsets()) {
1440                                allMap.put(t.getId().toLowerCase(), t);
1441                        }
1442                }
1443
1444                if (dataflow.getTables() != null) {
1445                        for (table t : dataflow.getTables()) {
1446                                allMap.put(t.getId().toLowerCase(), t);
1447                        }
1448                }
1449
1450                if (dataflow.getViews() != null) {
1451                        for (table t : dataflow.getViews()) {
1452                                allMap.put(t.getId().toLowerCase(), t);
1453                        }
1454                }
1455
1456                if (dataflow.getVariables() != null) {
1457                        for (table t : dataflow.getVariables()) {
1458                                allMap.put(t.getId().toLowerCase(), t);
1459                        }
1460                }
1461
1462                
1463                for (table resultSet : dataflow.getResultsets()) {
1464                        String resultSetName = DlineageUtil.getIdentifierNormalTableName(resultSet.getName());
1465                        if (!(ResultSetType.function.name().equals(resultSet.getType())
1466                                        && modelManager.getFunctionTable(resultSetName) != null && procedures.contains(resultSetName))) {
1467                                continue;
1468                        }
1469
1470                        Set<Object> functionTables = modelManager
1471                                        .getFunctionTable(DlineageUtil.getIdentifierNormalTableName(resultSet.getName()));
1472                        List<ResultSet> functionResults = functionTables.stream().filter(t -> t instanceof ResultSet)
1473                                        .map(t -> (ResultSet) t).collect(Collectors.toList());
1474                        if (!(resultSet.getColumns().size() == 1
1475                                        && DlineageUtil.getIdentifierNormalTableName(resultSet.getColumns().get(0).getName()).equals(resultSetName))
1476                                        || functionResults.isEmpty()) {
1477                                continue;
1478                        }
1479
1480                        column column = resultSet.getColumns().get(0);
1481                        String sourceColumnId = column.getId();
1482                        boolean reserveResultSet = false;
1483                        List<relationship> appendRelations = new ArrayList<relationship>();
1484                        Set<relationship> removeRelations = new HashSet<relationship>();
1485                        
1486                        for (relationship relationship : dataflow.getRelationships()) {
1487                                targetColumn targetColumn = relationship.getTarget();
1488                                List<sourceColumn> sourceColumns = relationship.getSources();
1489                                List<sourceColumn> newSourceColumns = new ArrayList<sourceColumn>();
1490                                for (sourceColumn sourceColumn : sourceColumns) {
1491                                        if (!sourceColumn.getId().equals(sourceColumnId)) {
1492                                                continue;
1493                                        }
1494                                        for (ResultSet sourceResultSet : functionResults) {
1495                                                for (ResultColumn resultColumn : sourceResultSet.getColumns()) {
1496                                                        if (!DlineageUtil.compareColumnIdentifier(resultColumn.getName(),
1497                                                                        targetColumn.getColumn())) {
1498                                                                if (targetColumn.getColumn().endsWith("*")) {
1499                                                                        table parent = allMap.get(targetColumn.getParent_id());
1500                                                                        if (parent != null && parent.getColumns().size() > 1) {
1501                                                                                for (column item : parent.getColumns()) {
1502                                                                                        if (DlineageUtil.compareColumnIdentifier(resultColumn.getName(),
1503                                                                                                        item.getName())) {
1504                                                                                                relationship newRelation = appendStarRelation(dataflow, relationship, item, resultColumn);
1505                                                                                                appendRelations.add(newRelation);
1506                                                                                                removeRelations.add(relationship);
1507                                                                                                newSourceColumns.add(newRelation.getSources().get(0));
1508                                                                                                if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) {
1509                                                                                                        dataflow.getResultsets().stream().filter(
1510                                                                                                                        t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId())))
1511                                                                                                                        .forEach(t -> t.setIsTarget(Boolean.FALSE.toString()));
1512                                                                                                }
1513                                                                                        }
1514                                                                                }
1515                                                                        }
1516                                                                }
1517                                                                continue;
1518                                                        }
1519                                                        
1520                                                        sourceColumn sourceColumn1 = new sourceColumn();
1521                                                        sourceColumn1.setId(String.valueOf(resultColumn.getId()));
1522                                                        sourceColumn1.setColumn(resultColumn.getName());
1523                                                        sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId()));
1524                                                        sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet()));
1525                                                        if (resultColumn.getStartPosition() != null
1526                                                                        && resultColumn.getEndPosition() != null) {
1527                                                                sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition())
1528                                                                                + "," + convertCoordinate(resultColumn.getEndPosition()));
1529                                                        }
1530                                                        newSourceColumns.add(sourceColumn1);
1531                                                        
1532                                                        if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) {
1533                                                                dataflow.getResultsets().stream().filter(
1534                                                                                t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId())))
1535                                                                                .forEach(t -> t.setIsTarget(Boolean.FALSE.toString()));
1536                                                        }
1537                                                }
1538                                        }
1539
1540                                        if (!newSourceColumns.isEmpty()) {
1541                                                if (removeRelations.isEmpty()) {
1542                                                        relationship.setSources(newSourceColumns);
1543                                                }
1544                                        }
1545                                        else {
1546                                                reserveResultSet = true;
1547                                        }
1548                                }
1549                        }
1550                        
1551                        dataflow.getRelationships().addAll(appendRelations);
1552                        dataflow.getRelationships().removeAll(removeRelations);
1553                        
1554                        if(!reserveResultSet) {
1555                                removeResultSets.add(resultSet);
1556                        }
1557                }
1558                dataflow.getResultsets().removeAll(removeResultSets);
1559                return dataflow;
1560        }
1561
1562        private relationship appendStarRelation(dataflow dataflow,
1563                        relationship relationship, column item, ResultColumn resultColumn) {
1564                relationship relationElement = new relationship();
1565                relationElement.setType(relationship.getType());
1566                relationElement.setEffectType(relationship.getEffectType());
1567                relationElement.setSqlHash(relationship.getSqlHash());
1568                relationElement.setSqlComment(relationship.getSqlComment());
1569                relationElement.setProcedureId(relationship.getProcedureId());
1570                relationElement.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID));
1571                relationElement.setProcessId(relationship.getProcessId());
1572                relationElement.setProcessType(relationship.getProcessType());
1573                
1574                targetColumn targetColumn1 = new targetColumn();
1575                targetColumn1.setId(String.valueOf(item.getId()));
1576                targetColumn1.setColumn(item.getName());
1577                targetColumn1.setParent_id(relationship.getTarget().getParent_id());
1578                targetColumn1.setParent_name(relationship.getTarget().getParent_name());
1579                targetColumn1.setParent_alias(relationship.getTarget().getParent_alias());
1580                if (relationship.getTarget().getCoordinate() != null) {
1581                        targetColumn1.setCoordinate(item.getCoordinate());
1582                }
1583                relationElement.setTarget(targetColumn1);       
1584                
1585                sourceColumn sourceColumn1 = new sourceColumn();
1586                sourceColumn1.setId(String.valueOf(resultColumn.getId()));
1587                sourceColumn1.setColumn(resultColumn.getName());
1588                sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId()));
1589                sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet()));
1590                if (resultColumn.getStartPosition() != null
1591                                && resultColumn.getEndPosition() != null) {
1592                        sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition())
1593                                        + "," + convertCoordinate(resultColumn.getEndPosition()));
1594                }
1595                relationElement.addSource(sourceColumn1);
1596                return relationElement;
1597        }
1598
1599        private dataflow getNormalizeDataflow(dataflow instance) {
1600                List<table> tables = new ArrayList<>();
1601                if (instance.getResultsets() != null) {
1602                        for (table t : instance.getResultsets()) {
1603                                tables.add(t);
1604                        }
1605                }
1606
1607                if (instance.getTables() != null) {
1608                        for (table t : instance.getTables()) {
1609                                tables.add(t);
1610                        }
1611                }
1612
1613                if (instance.getViews() != null) {
1614                        for (table t : instance.getViews()) {
1615                                tables.add(t);
1616                        }
1617                }
1618
1619                if (instance.getPaths() != null) {
1620                        for (table t : instance.getPaths()) {
1621                                tables.add(t);
1622                        }
1623                }
1624
1625                if (instance.getStages() != null) {
1626                        for (table t : instance.getStages()) {
1627                                tables.add(t);
1628                        }
1629                }
1630
1631                if (instance.getSequences() != null) {
1632                        for (table t : instance.getSequences()) {
1633                                tables.add(t);
1634                        }
1635                }
1636
1637                if (instance.getDatasources() != null) {
1638                        for (table t : instance.getDatasources()) {
1639                                tables.add(t);
1640                        }
1641                }
1642
1643                if (instance.getDatabases() != null) {
1644                        for (table t : instance.getDatabases()) {
1645                                tables.add(t);
1646                        }
1647                }
1648
1649                if (instance.getSchemas() != null) {
1650                        for (table t : instance.getSchemas()) {
1651                                tables.add(t);
1652                        }
1653                }
1654
1655                if (instance.getStreams() != null) {
1656                        for (table t : instance.getStreams()) {
1657                                tables.add(t);
1658                        }
1659                }
1660
1661                if (instance.getVariables() != null) {
1662                        for (table t : instance.getVariables()) {
1663                                tables.add(t);
1664                        }
1665                }
1666
1667                Map<String, String> idNameMap = new HashMap();
1668
1669                for(table table: tables){
1670                        if(table.getDatabase()!=null) {
1671                                table.setDatabase(DlineageUtil.getIdentifierNormalName(table.getDatabase(), ESQLDataObjectType.dotCatalog));
1672                        }
1673                        if(table.getSchema()!=null) {
1674                                table.setSchema(DlineageUtil.getIdentifierNormalName(table.getSchema(), ESQLDataObjectType.dotSchema));
1675                        }
1676                        if(table.getName()!=null) {
1677                                table.setName(DlineageUtil.getIdentifierNormalName(table.getName(), ESQLDataObjectType.dotTable));
1678                                idNameMap.put(table.getId(), table.getName());
1679                        }
1680                        if(table.getColumns()!=null){
1681                                for(column column: table.getColumns()){
1682                                        column.setName(DlineageUtil.getIdentifierNormalName(column.getName(), ESQLDataObjectType.dotColumn));
1683                                        idNameMap.put(column.getId(), column.getName());
1684                                }
1685                        }
1686                }
1687                if(instance.getPackages()!=null){
1688                        for(oraclePackage oraclePackage: instance.getPackages()){
1689                                if(oraclePackage.getDatabase()!=null) {
1690                                        oraclePackage.setDatabase(DlineageUtil.getIdentifierNormalName(oraclePackage.getDatabase(), ESQLDataObjectType.dotCatalog));
1691                                }
1692                                if(oraclePackage.getSchema()!=null) {
1693                                        oraclePackage.setSchema(DlineageUtil.getIdentifierNormalName(oraclePackage.getSchema(), ESQLDataObjectType.dotSchema));
1694                                }
1695                                if(oraclePackage.getName()!=null) {
1696                                        oraclePackage.setName(DlineageUtil.getIdentifierNormalName(oraclePackage.getName(), ESQLDataObjectType.dotTable));
1697                                        idNameMap.put(oraclePackage.getId(), oraclePackage.getName());
1698                                }
1699                                if(oraclePackage.getArguments()!=null){
1700                                        for(argument argument: oraclePackage.getArguments()){
1701                                                argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn));
1702                                                idNameMap.put(argument.getId(), argument.getName());
1703                                        }
1704                                }
1705                                if(oraclePackage.getProcedures()!=null){
1706                                        for(procedure procedure: oraclePackage.getProcedures()){
1707                                                if(procedure.getDatabase()!=null) {
1708                                                        procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog));
1709                                                }
1710                                                if(procedure.getSchema()!=null) {
1711                                                        procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema));
1712                                                }
1713                                                if(procedure.getName()!=null) {
1714                                                        procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable));
1715                                                        idNameMap.put(procedure.getId(), procedure.getName());
1716                                                }
1717                                                for(argument argument: procedure.getArguments()){
1718                                                        argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn));
1719                                                        idNameMap.put(argument.getId(), argument.getName());
1720                                                }
1721                                        }
1722                                }
1723                        }
1724                }
1725                if(instance.getProcedures()!=null){
1726                        for(procedure procedure: instance.getProcedures()){
1727                                if(procedure.getDatabase()!=null) {
1728                                        procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog));
1729                                }
1730                                if(procedure.getSchema()!=null) {
1731                                        procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema));
1732                                }
1733                                if(procedure.getName()!=null) {
1734                                        procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable));
1735                                        idNameMap.put(procedure.getId(), procedure.getName());
1736                                }
1737                                for(argument argument: procedure.getArguments()){
1738                                        argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn));
1739                                        idNameMap.put(argument.getId(), argument.getName());
1740                                }
1741                        }
1742                }
1743                if (instance.getProcesses() != null) {
1744                        for (process process : instance.getProcesses()) {
1745                                if(process.getDatabase()!=null) {
1746                                        process.setDatabase(DlineageUtil.getIdentifierNormalName(process.getDatabase(), ESQLDataObjectType.dotCatalog));
1747                                }
1748                                if(process.getSchema()!=null) {
1749                                        process.setSchema(DlineageUtil.getIdentifierNormalName(process.getSchema(), ESQLDataObjectType.dotSchema));
1750                                }
1751                                if (process.getProcedureId() != null) {
1752                                        process.setProcedureName(DlineageUtil.getIdentifierNormalName(process.getProcedureName(), ESQLDataObjectType.dotTable));
1753                                        idNameMap.put(process.getId(), process.getName());
1754                                }
1755                        }
1756                }
1757
1758                if(instance.getRelationships()!=null){
1759                        for(relationship relation: instance.getRelationships()){
1760                                targetColumn targetColumn = relation.getTarget();
1761                                if(targetColumn != null) {
1762                                        targetColumn.setColumn(idNameMap.get(targetColumn.getId()));
1763                                        targetColumn.setTarget_name(idNameMap.get(targetColumn.getTarget_id()));
1764                                        targetColumn.setParent_name(idNameMap.get(targetColumn.getParent_id()));
1765                                }
1766                                List<sourceColumn> sourceColumns = relation.getSources();
1767                                if(sourceColumns!=null){
1768                                        for(sourceColumn sourceColumn: sourceColumns){
1769                                                sourceColumn.setColumn(idNameMap.get(sourceColumn.getId()));
1770                                                sourceColumn.setSource_name(idNameMap.get(sourceColumn.getSource_id()));
1771                                                sourceColumn.setParent_name(idNameMap.get(sourceColumn.getParent_id()));
1772                                        }
1773                                }
1774                                targetColumn = relation.getCaller();
1775                                if(targetColumn != null) {
1776                                        targetColumn.setName(idNameMap.get(targetColumn.getId()));
1777                                }
1778                                sourceColumns = relation.getCallees();
1779                                if(sourceColumns!=null){
1780                                        for(sourceColumn sourceColumn: sourceColumns){
1781                                                sourceColumn.setName(idNameMap.get(sourceColumn.getId()));
1782                                        }
1783                                }
1784                        }
1785                }
1786
1787
1788                return instance;
1789        }
1790
1791        private dataflow filterDataflowCoordinate(dataflow instance) {
1792                List<table> tables = new ArrayList<>();
1793                if (instance.getResultsets() != null) {
1794                        for (table t : instance.getResultsets()) {
1795                                tables.add(t);
1796                        }
1797                }
1798
1799                if (instance.getTables() != null) {
1800                        for (table t : instance.getTables()) {
1801                                tables.add(t);
1802                        }
1803                }
1804
1805                if (instance.getViews() != null) {
1806                        for (table t : instance.getViews()) {
1807                                tables.add(t);
1808                        }
1809                }
1810
1811                if (instance.getPaths() != null) {
1812                        for (table t : instance.getPaths()) {
1813                                tables.add(t);
1814                        }
1815                }
1816
1817                if (instance.getStages() != null) {
1818                        for (table t : instance.getStages()) {
1819                                tables.add(t);
1820                        }
1821                }
1822
1823                if (instance.getSequences() != null) {
1824                        for (table t : instance.getSequences()) {
1825                                tables.add(t);
1826                        }
1827                }
1828
1829                if (instance.getDatasources() != null) {
1830                        for (table t : instance.getDatasources()) {
1831                                tables.add(t);
1832                        }
1833                }
1834
1835                if (instance.getDatabases() != null) {
1836                        for (table t : instance.getDatabases()) {
1837                                tables.add(t);
1838                        }
1839                }
1840
1841                if (instance.getSchemas() != null) {
1842                        for (table t : instance.getSchemas()) {
1843                                tables.add(t);
1844                        }
1845                }
1846
1847                if (instance.getStreams() != null) {
1848                        for (table t : instance.getStreams()) {
1849                                tables.add(t);
1850                        }
1851                }
1852
1853                if (instance.getVariables() != null) {
1854                        for (table t : instance.getVariables()) {
1855                                tables.add(t);
1856                        }
1857                }
1858
1859                for(table table: tables){
1860                        table.setCoordinate(null);
1861                        if(table.getColumns()!=null){
1862                                for(column column: table.getColumns()){
1863                                        column.setCoordinate(null);
1864                                }
1865                        }
1866                }
1867                if(instance.getPackages()!=null){
1868                        for(oraclePackage oraclePackage: instance.getPackages()){
1869                                oraclePackage.setCoordinate(null);
1870                                if(oraclePackage.getProcedures()!=null){
1871                                        for(procedure procedure: oraclePackage.getProcedures()){
1872                                                procedure.setCoordinate(null);
1873                                                for(argument argument: procedure.getArguments()){
1874                                                        argument.setCoordinate(null);
1875                                                }
1876                                        }
1877                                }
1878                        }
1879                }
1880                if(instance.getProcedures()!=null){
1881                        for(procedure procedure: instance.getProcedures()){
1882                                procedure.setCoordinate(null);
1883                                for(argument argument: procedure.getArguments()){
1884                                        argument.setCoordinate(null);
1885                                }
1886                        }
1887                }
1888                if (instance.getProcesses() != null) {
1889                        for (process process : instance.getProcesses()) {
1890                                process.setCoordinate(null);
1891                        }
1892                }
1893
1894                if(instance.getRelationships()!=null){
1895                        for(relationship relation: instance.getRelationships()){
1896                                targetColumn targetColumn = relation.getTarget();
1897                                if(targetColumn != null) {
1898                                        targetColumn.setCoordinate(null);
1899                                }
1900                                List<sourceColumn> sourceColumns = relation.getSources();
1901                                if(sourceColumns!=null){
1902                                        for(sourceColumn sourceColumn: sourceColumns){
1903                                                sourceColumn.setCoordinate(null);
1904                                        }
1905                                }
1906                                targetColumn = relation.getCaller();
1907                                if(targetColumn != null) {
1908                                        targetColumn.setCoordinate(null);
1909                                }
1910                                sourceColumns = relation.getCallees();
1911                                if(sourceColumns!=null){
1912                                        for(sourceColumn sourceColumn: sourceColumns){
1913                                                sourceColumn.setCoordinate(null);
1914                                        }
1915                                }
1916                        }
1917                }
1918
1919                return instance;
1920        }
1921
1922        private void appendSqlInfo(Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap, int index,
1923                        SqlInfo sqlInfo, Map queryObject) {
1924                EDbVendor vendor = option.getVendor();
1925                if (!SQLUtil.isEmpty(sqlInfo.getDbVendor())) {
1926                        vendor = EDbVendor.valueOf(sqlInfo.getDbVendor());
1927                }
1928
1929                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
1930                boolean supportSchema = TSQLEnv.supportSchema(vendor);
1931
1932                String content = (String) queryObject.get("sourceCode");
1933                if (SQLUtil.isEmpty(content)) {
1934                        return;
1935                }
1936                StringBuilder builder = new StringBuilder();
1937                if (supportCatalog) {
1938                        String database = (String) queryObject.get("database");
1939                        if (database.indexOf(".") != -1) {
1940                                String delimitedChar = TSQLEnv.delimitedChar(vendor);
1941                                database = delimitedChar + SQLUtil.trimColumnStringQuote(database) + delimitedChar;
1942                        }
1943                        builder.append(database);
1944                }
1945                if (supportSchema) {
1946                        String schema = (String) queryObject.get("schema");
1947                        if (schema.indexOf(".") != -1) {
1948                                String delimitedChar = TSQLEnv.delimitedChar(vendor);
1949                                schema = delimitedChar + SQLUtil.trimColumnStringQuote(schema) + delimitedChar;
1950                        }
1951                        if (builder.length() > 0) {
1952                                builder.append(".");
1953                        }
1954                        builder.append(schema);
1955                }
1956                String group = builder.toString();
1957                String sqlHash = SHA256.getMd5(content);
1958                String hash = SHA256.getMd5(sqlHash);
1959                if (!databaseMap.containsKey(sqlHash)) {
1960                        databaseMap.put(sqlHash,
1961                                        new Pair3<StringBuilder, AtomicInteger, String>(new StringBuilder(), new AtomicInteger(), group));
1962                }
1963                TGSqlParser parser = new TGSqlParser(option.getVendor());
1964                String delimiterChar = String.valueOf(parser.getDelimiterChar());
1965                StringBuilder buffer = new StringBuilder(content);
1966                if (content.trim().endsWith(delimiterChar) || content.trim().endsWith(";")) {
1967                        buffer.append("\n");
1968                } else if(vendor == EDbVendor.dbvredshift
1969                                || vendor == EDbVendor.dbvgaussdb
1970                                || vendor == EDbVendor.dbvpostgresql
1971                                || vendor == EDbVendor.dbvmysql
1972                                || vendor == EDbVendor.dbvteradata){
1973                        buffer.append("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n");
1974                } else{
1975                        SQLUtil.endTrim(buffer);
1976                        buffer.append(";").append("\n");
1977                }
1978
1979                int lineStart = databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1;
1980                if (databaseMap.get(sqlHash).first.toString().length() == 0) {
1981                        lineStart = 0;
1982                }
1983                databaseMap.get(sqlHash).first.append(buffer.toString());
1984                SqlInfo sqlInfoItem = new SqlInfo();
1985                sqlInfoItem.setServer(sqlInfo.getServer());
1986                sqlInfoItem.setDbVendor(sqlInfo.getDbVendor());
1987                sqlInfoItem.setFileName(sqlInfo.getFileName());
1988                sqlInfoItem.setFilePath(sqlInfo.getFilePath());
1989                sqlInfoItem.setSql(buffer.toString());
1990                sqlInfoItem.setOriginIndex(index);
1991                sqlInfoItem.setOriginLineStart(0);
1992                sqlInfoItem.setOriginLineEnd(buffer.toString().split("\n", -1).length - 1);
1993                sqlInfoItem.setIndex(databaseMap.get(sqlHash).second.getAndIncrement());
1994                sqlInfoItem.setLineStart(lineStart);
1995                sqlInfoItem.setLineEnd(databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1);
1996                sqlInfoItem.setGroup(group);
1997                sqlInfoItem.setHash(hash);
1998
1999                if (!sqlInfoMap.containsKey(hash)) {
2000                        sqlInfoMap.put(hash, new ArrayList<SqlInfo>());
2001                }
2002                sqlInfoMap.get(hash).add(sqlInfoItem);
2003        }
2004
2005        static String getTextOutput(dataflow dataflow) {
2006                StringBuffer buffer = new StringBuffer();
2007                List<relationship> relations = dataflow.getRelationships();
2008                if (relations != null) {
2009                        for (int i = 0; i < relations.size(); i++) {
2010                                relationship relation = relations.get(i);
2011                                targetColumn target = relation.getTarget();
2012                                List<sourceColumn> sources = relation.getSources();
2013                                if (target != null && sources != null && sources.size() > 0) {
2014                                        buffer.append(target.getColumn()).append(" depends on: ");
2015                                        Set<String> columnSet = new LinkedHashSet<String>();
2016                                        for (int j = 0; j < sources.size(); j++) {
2017                                                sourceColumn sourceColumn = sources.get(j);
2018                                                String columnName = sourceColumn.getColumn();
2019                                                if (sourceColumn.getParent_name() != null && sourceColumn.getParent_name().length() > 0) {
2020                                                        columnName = sourceColumn.getParent_name() + "." + columnName;
2021                                                }
2022                                                columnSet.add(columnName);
2023                                        }
2024                                        String[] columns = columnSet.toArray(new String[0]);
2025                                        for (int j = 0; j < columns.length; j++) {
2026                                                buffer.append(columns[j]);
2027                                                if (j == columns.length - 1) {
2028                                                        buffer.append("\n");
2029                                                } else
2030                                                        buffer.append(", ");
2031                                        }
2032                                }
2033                        }
2034                }
2035                return buffer.toString();
2036        }
2037
2038        private String mergeRelationType(List<Pair<sourceColumn, List<String>>> typePaths) {
2039                RelationshipType relationType = RelationshipType.join;
2040                for (int i = 0; i < typePaths.size(); i++) {
2041                        List<String> path = typePaths.get(i).second;
2042                        RelationshipType type = RelationshipType.valueOf(getRelationType(path));
2043                        if (type.ordinal() < relationType.ordinal()) {
2044                                relationType = type;
2045                        }
2046                }
2047                return relationType.name();
2048        }
2049
2050        private String getRelationType(List<String> typePaths) {
2051                if (typePaths.contains("join"))
2052                        return "join";
2053                if (typePaths.contains("fdr"))
2054                        return "fdr";
2055                if (typePaths.contains("frd"))
2056                        return "frd";
2057                if (typePaths.contains("fddi"))
2058                        return "fddi";
2059                return "fdd";
2060        }
2061
2062        public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput) throws Exception {
2063                return getSimpleDataflow(instance, simpleOutput, Arrays.asList("fdd"));
2064        }
2065        
2066        public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput, List<String> types) throws Exception {
2067                ModelBindingManager.setGlobalVendor(option.getVendor());
2068                allMap.clear();
2069                targetTables.clear();
2070                resultSetMap.clear();
2071                tableMap.clear();
2072                viewMap.clear();
2073                cursorMap.clear();
2074                variableMap.clear();
2075                fileMap.clear();
2076                stageMap.clear();
2077                sequenceMap.clear();
2078                dataSourceMap.clear();
2079                databaseMap.clear();
2080                schemaMap.clear();
2081                streamMap.clear();
2082                dataflow simple = new dataflow();
2083                List<relationship> simpleRelations = new ArrayList<relationship>();
2084                List<relationship> relations = instance.getRelationships();
2085                if (instance.getResultsets() != null) {
2086                        for (table t : instance.getResultsets()) {
2087                                resultSetMap.put(t.getId().toLowerCase(), t);
2088                                allMap.put(t.getId().toLowerCase(), t);
2089                        }
2090                }
2091
2092                if (instance.getTables() != null) {
2093                        for (table t : instance.getTables()) {
2094                                tableMap.put(t.getId().toLowerCase(), t);
2095                                allMap.put(t.getId().toLowerCase(), t);
2096                        }
2097                }
2098
2099                if (instance.getViews() != null) {
2100                        for (table t : instance.getViews()) {
2101                                viewMap.put(t.getId().toLowerCase(), t);
2102                                allMap.put(t.getId().toLowerCase(), t);
2103                        }
2104                }
2105
2106                if (instance.getPaths() != null) {
2107                        for (table t : instance.getPaths()) {
2108                                fileMap.put(t.getId().toLowerCase(), t);
2109                                allMap.put(t.getId().toLowerCase(), t);
2110                        }
2111                }
2112
2113                if (instance.getStages() != null) {
2114                        for (table t : instance.getStages()) {
2115                                stageMap.put(t.getId().toLowerCase(), t);
2116                                allMap.put(t.getId().toLowerCase(), t);
2117                        }
2118                }
2119                
2120                if (instance.getSequences() != null) {
2121                        for (table t : instance.getSequences()) {
2122                                sequenceMap.put(t.getId().toLowerCase(), t);
2123                                allMap.put(t.getId().toLowerCase(), t);
2124                        }
2125                }
2126
2127                if (instance.getDatasources() != null) {
2128                        for (table t : instance.getDatasources()) {
2129                                dataSourceMap.put(t.getId().toLowerCase(), t);
2130                                allMap.put(t.getId().toLowerCase(), t);
2131                        }
2132                }
2133
2134                if (instance.getDatabases() != null) {
2135                        for (table t : instance.getDatabases()) {
2136                                databaseMap.put(t.getId().toLowerCase(), t);
2137                                allMap.put(t.getId().toLowerCase(), t);
2138                        }
2139                }
2140
2141                if (instance.getSchemas() != null) {
2142                        for (table t : instance.getSchemas()) {
2143                                schemaMap.put(t.getId().toLowerCase(), t);
2144                                allMap.put(t.getId().toLowerCase(), t);
2145                        }
2146                }
2147
2148                if (instance.getStreams() != null) {
2149                        for (table t : instance.getStreams()) {
2150                                streamMap.put(t.getId().toLowerCase(), t);
2151                                allMap.put(t.getId().toLowerCase(), t);
2152                        }
2153                }
2154
2155                if (instance.getVariables() != null) {
2156                        for (table t : instance.getVariables()) {
2157                                if(SubType.cursor.name().equals(t.getSubType())){
2158                                        cursorMap.put(t.getId().toLowerCase(), t);
2159                                }
2160                                else {
2161                                        variableMap.put(t.getId().toLowerCase(), t);
2162                                }
2163                                allMap.put(t.getId().toLowerCase(), t);
2164                        }
2165                }
2166
2167                if (relations != null) {
2168                        
2169                        List<relationship> filterRelations = new ArrayList<>();
2170                        for (relationship relationElem : relations) {
2171                                if (!types.contains(relationElem.getType()))
2172                                        continue;
2173                                else {
2174                                        filterRelations.add(relationElem);
2175                                }
2176                        }
2177                        
2178                        relations = filterRelations;
2179                        
2180                        Map<String, Set<relationship>> targetIdRelationMap = new HashMap<String, Set<relationship>>();
2181                        for (relationship relation : relations) {
2182                                if (relation.getTarget() != null) {
2183                                        String key = relation.getTarget().getParent_id() + "." + relation.getTarget().getId();
2184                                        if (!targetIdRelationMap.containsKey(key)) {
2185                                                targetIdRelationMap.put(key, new TreeSet<relationship>(new Comparator<relationship>() {
2186                                                        @Override
2187                                                        public int compare(relationship o1, relationship o2) {
2188                                                                return o1.getId().compareTo(o2.getId());
2189                                                        }
2190                                                }));
2191                                        }
2192                                        targetIdRelationMap.get(key).add(relation);
2193                                }
2194                        }
2195
2196                        Iterator<String> keys = targetIdRelationMap.keySet().iterator();
2197                        while (keys.hasNext()) {
2198                                String key = keys.next();
2199                                if (targetIdRelationMap.get(key).size() > 500) {
2200                                        keys.remove();
2201                                }
2202                        }
2203
2204                        for (relationship relationElem : relations) {
2205                                if (option.isShowCallRelation()) {
2206                                        if (RelationshipType.call.name().equals(relationElem.getType())) {
2207                                                continue;
2208                                        }
2209                                }
2210                                targetColumn target = relationElem.getTarget();
2211                                String targetParent = target.getParent_id();
2212                                if (isTarget(instance, targetParent, simpleOutput)) {
2213                                        List<Pair<sourceColumn, List<String>>> relationSources = new ArrayList<Pair<sourceColumn, List<String>>>();
2214                                        findSourceRelations(target, instance, targetIdRelationMap, relationElem, relationSources,
2215                                                        new String[] { relationElem.getType() }, simpleOutput);
2216                                        if (relationSources.size() > 0) {
2217                                                Map<sourceColumn, List<Pair<sourceColumn, List<String>>>> columnMap = new LinkedHashMap<sourceColumn, List<Pair<sourceColumn, List<String>>>>();
2218                                                for (Pair<sourceColumn, List<String>> t : relationSources) {
2219                                                        sourceColumn key = ((Pair<sourceColumn, List<String>>) t).first;
2220                                                        if (!columnMap.containsKey(key)) {
2221                                                                columnMap.put(key, new ArrayList<Pair<sourceColumn, List<String>>>());
2222                                                        }
2223                                                        columnMap.get(key).add(t);
2224                                                }
2225                                                Iterator<sourceColumn> iter = columnMap.keySet().iterator();
2226                                                Map<String, List<sourceColumn>> relationSourceMap = new HashMap<String, List<sourceColumn>>();
2227                                                while (iter.hasNext()) {
2228                                                        sourceColumn column = iter.next();
2229                                                        String relationType = mergeRelationType(columnMap.get(column));
2230                                                        if (!relationSourceMap.containsKey(relationType)) {
2231                                                                relationSourceMap.put(relationType, new ArrayList<sourceColumn>());
2232                                                        }
2233                                                        relationSourceMap.get(relationType).add(column);
2234                                                }
2235
2236                                                Iterator<String> sourceIter = relationSourceMap.keySet().iterator();
2237                                                while (sourceIter.hasNext()) {
2238                                                        String relationType = sourceIter.next();
2239                                                        relationship simpleRelation = (relationship) relationElem.clone();
2240                                                        simpleRelation.setSources(relationSourceMap.get(relationType));
2241                                                        simpleRelation.setType(relationType);
2242                                                        simpleRelation.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID));
2243                                                        simpleRelations.add(simpleRelation);
2244                                                }
2245                                        }
2246                                }
2247                        }
2248                }
2249
2250                simple.setProcedures(instance.getProcedures());
2251                simple.setPackages(instance.getPackages());
2252                simple.setProcesses(instance.getProcesses());
2253                simple.setErrors(instance.getErrors());
2254                List<table> tables = new ArrayList<table>();
2255                for (table t : instance.getTables()) {
2256                        if (!SQLUtil.isTempTable(t)) {
2257                                tables.add(t);
2258                        }
2259                        else {
2260                                if (option.isIgnoreTemporaryTable()) {
2261                                        continue;
2262                                }
2263                                else {
2264                                        tables.add(t);
2265                                }
2266                        }
2267                }
2268                simple.setStages(instance.getStages());
2269                simple.setSequences(instance.getSequences());
2270                simple.setDatasources(instance.getDatasources());
2271                simple.setStreams(instance.getStreams());
2272                simple.setPaths(instance.getPaths());
2273                simple.setTables(tables);
2274                simple.setViews(instance.getViews());
2275                if(option.isSimpleShowVariable()) {
2276                        simple.setVariables(instance.getVariables());
2277                }
2278                else if(option.isSimpleShowCursor()) {
2279                        simple.setVariables(instance.getVariables().stream().filter(t->SubType.cursor.name().equals(t.getSubType())).collect(Collectors.toList()));
2280                }
2281                if (instance.getResultsets() != null) {
2282                        List<table> resultSets = new ArrayList<table>();
2283                        for (int i = 0; i < instance.getResultsets().size(); i++) {
2284                                table resultSet = instance.getResultsets().get(i);
2285                                if (isTargetResultSet(instance, resultSet.getId(), simpleOutput)) {
2286                                        // special handle function #524 #296
2287                                        resultSets.add(resultSet);
2288                                }
2289                        }
2290                        simple.setResultsets(resultSets);
2291                }
2292
2293                List<table> functions = new ArrayList<table>();
2294                if (option.isShowCallRelation()) {
2295                        for (int i = 0; i < relations.size(); i++) {
2296                                relationship relationElem = relations.get(i);
2297                                if (!RelationshipType.call.name().equals(relationElem.getType())) {
2298                                        continue;
2299                                }
2300                                simpleRelations.add(relationElem);
2301                                for (sourceColumn callee : relationElem.getCallees()) {
2302                                        String calleeId = callee.getId();
2303                                        if (resultSetMap.containsKey(calleeId)) {
2304                                                table function = resultSetMap.get(calleeId);
2305                                                function.setIsTarget("true");
2306                                                functions.add(function);
2307                                        }
2308                                }
2309                        }
2310                }
2311
2312                if (option.isShowERDiagram()) {
2313                        for (int i = 0; i < relations.size(); i++) {
2314                                relationship relationElem = relations.get(i);
2315                                if (!RelationshipType.er.name().equals(relationElem.getType())) {
2316                                        continue;
2317                                }
2318                                simpleRelations.add(relationElem);
2319                                for (sourceColumn callee : relationElem.getCallees()) {
2320                                        String calleeId = callee.getId();
2321                                        if (resultSetMap.containsKey(calleeId)) {
2322                                                table function = resultSetMap.get(calleeId);
2323                                                function.setIsTarget("true");
2324                                                functions.add(function);
2325                                        }
2326                                }
2327                        }
2328                }
2329                
2330                if (!functions.isEmpty()) {
2331                        if (simple.getResultsets() == null) {
2332                                simple.setResultsets(functions);
2333                        } else {
2334                                simple.getResultsets().addAll(functions);
2335                        }
2336                }
2337
2338                simple.setRelationships(simpleRelations);
2339                simple.setOrientation(instance.getOrientation());
2340                targetTables.clear();
2341                resultSetMap.clear();
2342                tableMap.clear();
2343                viewMap.clear();
2344                cursorMap.clear();
2345                variableMap.clear();
2346                fileMap.clear();
2347                stageMap.clear();
2348                dataSourceMap.clear();
2349                databaseMap.clear();
2350                schemaMap.clear();
2351                streamMap.clear();
2352                return simple;
2353        }
2354
2355        private void findSourceRelations(targetColumn target, dataflow instance, Map<String, Set<relationship>> sourceIdRelationMap,
2356                        relationship targetRelation, List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, boolean simpleOutput) {
2357                findStarSourceRelations(target, instance, null, sourceIdRelationMap, targetRelation, relationSources, pathTypes,
2358                                new HashSet<String>(), new LinkedHashSet<transform>(), new LinkedHashSet<candidateTable>(), 0, simpleOutput);
2359        }
2360
2361        private void findStarSourceRelations(targetColumn target, dataflow instance, targetColumn starRelationTarget,
2362                        Map<String, Set<relationship>> sourceIdRelationMap, relationship targetRelation,
2363                        List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, Set<String> paths,
2364                        Set<transform> transforms, Set<candidateTable> candidateTables, int level, boolean simpleOutput) {
2365                if (targetRelation != null && targetRelation.getSources() != null) {
2366                        
2367                        //获取source为*的Column Parent
2368                        String starParentId = null;
2369                        for (int i = 0; i < targetRelation.getSources().size(); i++) {
2370                                sourceColumn source = targetRelation.getSources().get(i);
2371                                if (starRelationTarget != null && "*".equals(source.getColumn())) {
2372                                        starParentId = source.getParent_id();
2373                                }
2374                        }
2375                        
2376                        for (int i = 0; i < targetRelation.getSources().size(); i++) {
2377                                sourceColumn source = targetRelation.getSources().get(i);
2378                                if (starRelationTarget != null && !"*".equals(source.getColumn())
2379                                                && !DlineageUtil.getIdentifierNormalColumnName(starRelationTarget.getColumn())
2380                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(source.getColumn()))) {
2381                                        table parent = allMap.get(source.getParent_id());
2382                                        if (parent != null && isFunction(parent)) {
2383                                                // function返回值未知,不对星号做处理
2384                                        } 
2385                                        else if (parent == null) {
2386                                                continue;
2387                                        } else if(starParentId!=null && starParentId.equals(parent.getId())){
2388                                                //如果source和 * column的parent相同,则跳过
2389                                                continue;
2390                                        }
2391                                }
2392
2393                                String sourceColumnId = source.getId();
2394                                String sourceParentId = source.getParent_id();
2395                                if (sourceParentId == null || sourceColumnId == null) {
2396                                        continue;
2397                                }
2398                                if (isTarget(instance, sourceParentId, simpleOutput)) {
2399                                        List<transform> transforms2 = new ArrayList<transform>(transforms.size());
2400                                        transforms2.addAll(transforms);
2401                                        Collections.reverse(transforms2);
2402                                        
2403                                        List<candidateTable> candidateTables2 = new ArrayList<candidateTable>(candidateTables.size());
2404                                        candidateTables2.addAll(candidateTables);
2405                                        
2406                                        sourceColumn sourceColumnCopy = DlineageUtil.copySourceColumn(source);
2407                                        for (transform t : transforms2) {
2408                                                sourceColumnCopy.addTransform(t);
2409                                        }
2410                                        
2411                                        for (candidateTable t : candidateTables2) {
2412                                                sourceColumnCopy.addCandidateParent(t);
2413                                        }
2414                                        
2415                                        if(Boolean.TRUE.equals(target.isStruct()) && Boolean.TRUE.equals(source.isStruct())) {
2416                                                List<String> targetColumns = SQLUtil.parseNames(target.getColumn());
2417                                                List<String> sourceColumns = SQLUtil.parseNames(source.getColumn());
2418                                                if(!DlineageUtil.getIdentifierNormalColumnName(targetColumns.get(targetColumns.size()-1))
2419                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(sourceColumns.get(sourceColumns.size()-1)))) {
2420                                                        continue;
2421                                                }
2422                                        }
2423                                        relationSources.add(new Pair<sourceColumn, List<String>>(sourceColumnCopy, Arrays.asList(pathTypes)));
2424                                } else {
2425                                        Set<relationship> sourceRelations = sourceIdRelationMap
2426                                                        .get(source.getParent_id() + "." + source.getId());
2427                                        if (sourceRelations != null) {
2428                                                if (paths.contains(source.getParent_id() + "." + source.getId())) {
2429                                                        continue;
2430                                                } else {
2431                                                        paths.add(source.getParent_id() + "." + source.getId());
2432                                                        if (source.getTransforms() != null) {
2433                                                                transforms.addAll(source.getTransforms());
2434                                                        }
2435                                                        if (source.getCandidateParents() != null) {
2436                                                                candidateTables.addAll(source.getCandidateParents());
2437                                                        }
2438                                                }
2439                                                for (relationship relation : sourceRelations) {
2440                                                        LinkedHashSet<transform> transforms2 = new LinkedHashSet<transform>(transforms.size());
2441                                                        transforms2.addAll(transforms);
2442                                                        LinkedHashSet<candidateTable> candidateTables2 = new LinkedHashSet<candidateTable>(candidateTables.size());
2443                                                        candidateTables2.addAll(candidateTables);
2444                                                        String[] types = new String[pathTypes.length + 1];
2445                                                        types[0] = relation.getType();
2446                                                        System.arraycopy(pathTypes, 0, types, 1, pathTypes.length);
2447                                                        if (!"*".equals(source.getColumn())) {
2448                                                                findStarSourceRelations(target, instance, null, sourceIdRelationMap, relation, relationSources,
2449                                                                                types, paths, transforms2, candidateTables2, level + 1, simpleOutput);
2450                                                        } else {
2451                                                                findStarSourceRelations(target, instance,
2452                                                                                starRelationTarget == null ? targetRelation.getTarget() : starRelationTarget,
2453                                                                                sourceIdRelationMap, relation, relationSources, types, paths, transforms, candidateTables2,
2454                                                                                level + 1, simpleOutput);
2455                                                        }
2456                                                }
2457                                        }
2458                                }
2459                        }
2460                }
2461        }
2462
2463        private Map<String, Boolean> targetTables = new HashMap<String, Boolean>();
2464        private Map<String, table> resultSetMap = new HashMap<String, table>();
2465        private Map<String, table> tableMap = new HashMap<String, table>();
2466        private Map<String, table> viewMap = new HashMap<String, table>();
2467        private Map<String, table> cursorMap = new HashMap<String, table>();
2468        private Map<String, table> variableMap = new HashMap<String, table>();
2469        private Map<String, table> fileMap = new HashMap<String, table>();
2470        private Map<String, table> stageMap = new HashMap<String, table>();
2471        private Map<String, table> sequenceMap = new HashMap<String, table>();
2472        private Map<String, table> dataSourceMap = new HashMap<String, table>();
2473        private Map<String, table> databaseMap = new HashMap<String, table>();
2474        private Map<String, table> schemaMap = new HashMap<String, table>();
2475        private Map<String, table> streamMap = new HashMap<String, table>();
2476        private Map<String, table> allMap = new HashMap<String, table>();
2477
2478        private boolean isTarget(dataflow instance, String targetParentId, boolean simpleOutput) {
2479                if (targetTables.containsKey(targetParentId))
2480                        return targetTables.get(targetParentId);
2481                if (isTable(instance, targetParentId)) {
2482                        targetTables.put(targetParentId, true);
2483                        return true;
2484                } else if (isView(instance, targetParentId)) {
2485                        targetTables.put(targetParentId, true);
2486                        return true;
2487                } else if (isFile(instance, targetParentId)) {
2488                        targetTables.put(targetParentId, true);
2489                        return true;
2490                } else if (isDatabase(instance, targetParentId)) {
2491                        targetTables.put(targetParentId, true);
2492                        return true;
2493                } else if (isSchema(instance, targetParentId)) {
2494                        targetTables.put(targetParentId, true);
2495                        return true;
2496                } else if (isStage(instance, targetParentId)) {
2497                        targetTables.put(targetParentId, true);
2498                        return true;
2499                } else if (isSequence(instance, targetParentId)) {
2500                        targetTables.put(targetParentId, true);
2501                        return true;
2502                } else if (isDataSource(instance, targetParentId)) {
2503                        targetTables.put(targetParentId, true);
2504                        return true;
2505                } else if (isStream(instance, targetParentId)) {
2506                        targetTables.put(targetParentId, true);
2507                        return true;
2508                } else if (isCursor(instance, targetParentId) && option.isSimpleShowCursor()) {
2509                        targetTables.put(targetParentId, true);
2510                        return true;
2511                } else if ((isVariable(instance, targetParentId) || isCursor(instance, targetParentId)) && option.isSimpleShowVariable()) {
2512                        targetTables.put(targetParentId, true);
2513                        return true;
2514                } else if (isTargetResultSet(instance, targetParentId, simpleOutput)) {
2515                        targetTables.put(targetParentId, true);
2516                        return true;
2517                }
2518                targetTables.put(targetParentId, false);
2519                return false;
2520        }
2521
2522        private boolean isTargetResultSet(dataflow instance, String targetParent, boolean simpleOutput) {
2523                if (resultSetMap.containsKey(targetParent.toLowerCase())) {
2524                        table result = resultSetMap.get(targetParent.toLowerCase());
2525                        boolean isTarget = result.isTarget();
2526                        Option option = ModelBindingManager.getGlobalOption();
2527                        if (option != null && option.isSqlflowIgnoreFunction() && isFunction(result)) {
2528                                return false;
2529                        }
2530                        if (isTarget && simpleOutput) {
2531                                if (option != null && option.isSimpleShowFunction() && isFunction(result)) {
2532                                        return true;
2533
2534                                } else if (option != null && option.isSimpleShowTopSelectResultSet()) {
2535                                        return true;
2536                                }
2537                                if (ResultSetType.of(result.getType()) != null && option.containsResultSetType(ResultSetType.of(result.getType()))) {
2538                                        return true;
2539                                }
2540                        } else
2541                                return isTarget;
2542                }
2543                return false;
2544        }
2545
2546        private boolean isFunction(table resultSet) {
2547                if("function".equals(resultSet.getType())){
2548                        return true;
2549                }
2550                else if("resultset".equals(resultSet.getType()) && "function".equals(resultSet.getSubType())){
2551                        return true;
2552                }
2553                return false;
2554        }
2555
2556        private boolean isView(dataflow instance, String targetParent) {
2557                if (viewMap.containsKey(targetParent.toLowerCase())) {
2558                        return true;
2559                }
2560                return false;
2561        }
2562
2563        private boolean isCursor(dataflow instance, String targetParent) {
2564                if (cursorMap.containsKey(targetParent.toLowerCase())) {
2565                        return true;
2566                }
2567                return false;
2568        }
2569
2570        private boolean isVariable(dataflow instance, String targetParent) {
2571                if (variableMap.containsKey(targetParent.toLowerCase())) {
2572                        return true;
2573                }
2574                return false;
2575        }
2576
2577        private boolean isFile(dataflow instance, String targetParent) {
2578                if (fileMap.containsKey(targetParent.toLowerCase())) {
2579                        return true;
2580                }
2581                return false;
2582        }
2583
2584        private boolean isStage(dataflow instance, String targetParent) {
2585                if (stageMap.containsKey(targetParent.toLowerCase())) {
2586                        return true;
2587                }
2588                return false;
2589        }
2590        
2591        private boolean isSequence(dataflow instance, String targetParent) {
2592                if (sequenceMap.containsKey(targetParent.toLowerCase())) {
2593                        return true;
2594                }
2595                return false;
2596        }
2597
2598        private boolean isDataSource(dataflow instance, String targetParent) {
2599                if (dataSourceMap.containsKey(targetParent.toLowerCase())) {
2600                        return true;
2601                }
2602                return false;
2603        }
2604
2605        private boolean isDatabase(dataflow instance, String targetParent) {
2606                if (databaseMap.containsKey(targetParent.toLowerCase())) {
2607                        return true;
2608                }
2609                return false;
2610        }
2611
2612        private boolean isSchema(dataflow instance, String targetParent) {
2613                if (schemaMap.containsKey(targetParent.toLowerCase())) {
2614                        return true;
2615                }
2616                return false;
2617        }
2618
2619        private boolean isStream(dataflow instance, String targetParent) {
2620                if (streamMap.containsKey(targetParent.toLowerCase())) {
2621                        return true;
2622                }
2623                return false;
2624        }
2625
2626        private boolean isTable(dataflow instance, String targetParent) {
2627                if (tableMap.containsKey(targetParent.toLowerCase())) {
2628                        if (SQLUtil.isTempTable(tableMap.get(targetParent))) {
2629                                if (option.isIgnoreTemporaryTable()) {
2630                                        return false;
2631                                }
2632                        }
2633                        if (tableMap.get(targetParent).isFunction()) {
2634                                if (option != null && option.isSimpleShowFunction()) {
2635                                        return true;
2636                                } else {
2637                                        return false;
2638                                }
2639                        }
2640                        if (SubType.synonym.name().equals(tableMap.get(targetParent).getSubType())) {
2641                                if (option != null && option.isSimpleShowSynonym()) {
2642                                        return true;
2643                                } else {
2644                                        return false;
2645                                }
2646                        }
2647                        return true;
2648                } else {
2649                        return false;
2650                }
2651        }
2652
2653        private void init() {
2654                metadataErrors.clear();
2655                sqlInfoMap.clear();
2656                errorInfos.clear();
2657                dataflow = null;
2658                dataflowString = null;
2659                ModelBindingManager.removeGlobalDatabase();
2660                ModelBindingManager.removeGlobalSchema();
2661                ModelBindingManager.removeGlobalVendor();
2662                ModelBindingManager.removeGlobalSQLEnv();
2663                ModelBindingManager.removeGlobalHash();
2664                appendResultSets.clear();
2665                appendStarColumns.clear();
2666                appendTableStarColumns.clear();
2667                modelManager.TABLE_COLUMN_ID = option.getStartId();
2668                modelManager.RELATION_ID = option.getStartId();
2669                modelManager.DISPLAY_ID.clear();
2670                modelManager.DISPLAY_NAME.clear();
2671                tableIds.clear();
2672                ModelBindingManager.setGlobalVendor(option.getVendor());
2673                modelManager.reset();
2674        }
2675
2676        private String getErrorMessage(TSyntaxError error, String errorType) {
2677                String s = "", hint = "Syntax error";
2678                if (ErrorInfo.SYNTAX_HINT.equals(errorType)) {
2679                        hint = "Syntax hint";
2680                }
2681                if (error.hint.length() > 0)
2682                        hint = error.hint;
2683                s = s + hint + "(" + error.errorno + ") near: " + error.tokentext;
2684                s = s + "(" + error.lineNo;
2685                s = s + "," + error.columnNo + ")";
2686                return s;
2687        }
2688
2689        boolean OLD_ENABLE_RESOLVER = TBaseType.isEnableResolver();
2690        private void analyzeAndOutputResult(TGSqlParser sqlparser) {
2691                try {
2692                        accessedSubqueries.clear();
2693                        accessedStatements.clear();
2694                        stmtStack.clear();
2695                        viewDDLMap.clear();
2696                        procedureDDLMap.clear();
2697                        OLD_ENABLE_RESOLVER = TBaseType.isEnableResolver();
2698                        // Only enable old resolver if TSQLResolver2 is not enabled
2699                        if (!TBaseType.isEnableResolver2()) {
2700                                TBaseType.setEnableResolver(true);
2701                        }
2702                        try {
2703                                if(sqlenv!=null) {
2704                                        sqlparser.setSqlEnv(sqlenv);
2705                                }
2706                                int result = sqlparser.parse();
2707                                if (result != 0) {
2708                                        ArrayList<TSyntaxError> errors = sqlparser.getSyntaxErrors();
2709                                        if (errors != null && !errors.isEmpty()) {
2710                                                for (int i = 0; i < errors.size(); i++) {
2711                                                        TSyntaxError error = errors.get(i);
2712                                                        ErrorInfo errorInfo = new ErrorInfo();
2713                                                        errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
2714                                                        errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
2715                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2716                                                                        ModelBindingManager.getGlobalHash()));
2717                                                        String[] segments = error.tokentext.split("\n");
2718                                                        if (segments.length == 1) {
2719                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2720                                                                                error.columnNo + error.tokentext.length(),
2721                                                                                ModelBindingManager.getGlobalHash()));
2722                                                        } else {
2723                                                                errorInfo.setEndPosition(
2724                                                                                new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2725                                                                                                (long) segments[segments.length - 1].length() + 1,
2726                                                                                                ModelBindingManager.getGlobalHash()));
2727                                                        }
2728                                                        ;
2729                                                        errorInfo.fillInfo(this);
2730                                                        errorInfos.add(errorInfo);
2731                                                }
2732                                        }
2733                                }
2734
2735                                if (option.getHandleListener() != null) {
2736                                        option.getHandleListener().endParse(result == 0);
2737                                }
2738                        } catch (Exception e) {
2739                                if (option.getHandleListener() != null) {
2740                                        option.getHandleListener().endParse(false);
2741                                }
2742                                ErrorInfo errorInfo = new ErrorInfo();
2743                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
2744                                if (e.getMessage() == null) {
2745                                        if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
2746                                                errorInfo
2747                                                                .setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
2748                                        } else {
2749                                                errorInfo.setErrorMessage(e.getClass().getSimpleName());
2750                                        }
2751                                } else {
2752                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
2753                                }
2754                                errorInfo.fillInfo(this);
2755                                errorInfos.add(errorInfo);
2756                                return;
2757                        }
2758
2759                        if (option.getHandleListener() != null) {
2760                                option.getHandleListener().startAnalyzeDataFlow(sqlparser);
2761                        }
2762
2763                        for (int i = 0; i < sqlparser.getSqlstatements().size(); i++) {
2764                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2765                                        break;
2766                                }
2767
2768                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2769                                if (stmt.getErrorCount() == 0) {
2770                                        if (stmt.getParentStmt() == null) {
2771                                                modelManager.collectSqlHash(stmt);
2772                                                if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema
2773                                                                || stmt instanceof TCreateTableSqlStatement
2774                                                                || stmt instanceof TCreateExternalDataSourceStmt || stmt instanceof TCreateStageStmt
2775                                                                || stmt instanceof TMssqlCreateType
2776                                                                || stmt instanceof TMssqlDeclare
2777                                                                || (stmt instanceof TCreateFunctionStmt && hasDb2ReturnStmt((TCreateFunctionStmt)stmt))
2778                                                                || (stmt instanceof TMssqlCreateFunction
2779                                                                                && (((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null
2780                                                                                                || ((TMssqlCreateFunction) stmt).getReturnStmt() != null))) {
2781                                                        boolean listen = false;
2782                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2783                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2784                                                                listen = true;
2785                                                        }
2786                                                        analyzeCustomSqlStmt(stmt);
2787                                                        if (listen && option.getHandleListener() != null) {
2788                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2789                                                        }
2790                                                }
2791                                        }
2792                                }
2793                        }
2794
2795                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2796                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2797                                        break;
2798                                }
2799
2800                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2801                                if (stmt.getErrorCount() == 0) {
2802                                        if (stmt.getParentStmt() == null) {
2803                                                if (stmt instanceof TUseDatabase 
2804                                                                || stmt instanceof TUseSchema
2805                                                                || stmt instanceof TCreateViewSqlStatement 
2806                                                                || stmt instanceof TCreateSynonymStmt 
2807                                                                || stmt instanceof TStoredProcedureSqlStatement) {
2808                                                        boolean listen = false;
2809                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2810                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2811                                                                listen = true;
2812                                                        }
2813                                                        if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema) {
2814                                                                analyzeCustomSqlStmt(stmt);
2815                                                        } else if (stmt instanceof TCreateViewSqlStatement) {
2816                                                                TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt;
2817                                                                viewDDLMap.put(DlineageUtil.getTableFullName(view.getViewName().toString()), view);
2818                                                        } else if (stmt instanceof TCreateSynonymStmt) {
2819                                                                TCreateSynonymStmt synonym = (TCreateSynonymStmt) stmt;
2820                                                                if(synonym.getSynonymName()!=null) {
2821                                                                        viewDDLMap.put(DlineageUtil.getTableFullName(synonym.getSynonymName().toString()), synonym);
2822                                                                }
2823                                                        } else if (stmt instanceof TStoredProcedureSqlStatement) {
2824                                                                TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) stmt;
2825                                                                if(procedure.getStoredProcedureName() == null) {
2826                                                                        continue;
2827                                                                }
2828                                                                procedureDDLMap.put(DlineageUtil.getProcedureNameWithArgNum(procedure), procedure);
2829                                                        }
2830                                                        if (listen && option.getHandleListener() != null) {
2831                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2832                                                        }
2833                                                }
2834                                        }
2835                                }
2836                        }
2837
2838                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2839                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2840                                        break;
2841                                }
2842
2843                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2844                                if (stmt.getErrorCount() == 0) {
2845                                        if (stmt.getParentStmt() == null) {
2846                                                if (stmt instanceof TUseDatabase 
2847                                                                || stmt instanceof TUseSchema
2848                                                                || stmt instanceof TCreateViewSqlStatement 
2849                                                                || stmt instanceof TCreateSynonymStmt) {
2850                                                        boolean listen = false;
2851                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2852                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2853                                                                listen = true;
2854                                                        }
2855                                                        analyzeCustomSqlStmt(stmt);
2856                                                        if (listen && option.getHandleListener() != null) {
2857                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2858                                                        }
2859                                                }
2860                                        }
2861                                }
2862                        }
2863
2864                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2865                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2866                                        break;
2867                                }
2868
2869                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2870                                if (stmt.getErrorCount() == 0) {
2871                                        if (stmt.getParentStmt() == null) {
2872                                                if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema
2873                                                                || stmt instanceof TStoredProcedureSqlStatement) {
2874                                                        boolean listen = false;
2875                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2876                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2877                                                                listen = true;
2878                                                        }
2879                                                        if (stmt instanceof TPlsqlCreateTrigger)
2880                                                                continue;
2881                                                        analyzeCustomSqlStmt(stmt);
2882                                                        if (listen && option.getHandleListener() != null) {
2883                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2884                                                        }
2885                                                }
2886                                        }
2887                                }
2888                        }
2889
2890                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2891                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2892                                        break;
2893                                }
2894
2895                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2896
2897                                if (option.isIgnoreTopSelect()) {
2898                                        if ((stmt instanceof TSelectSqlStatement && ((TSelectSqlStatement)stmt).getIntoClause() == null && ((TSelectSqlStatement)stmt).getIntoTableClause() == null ) || stmt instanceof TRedshiftDeclare
2899                                                        || stmt instanceof TRedshiftDeclare) {
2900                                                continue;
2901                                        }
2902                                }
2903
2904                                if (stmt.getErrorCount() == 0) {
2905                                        if (stmt.getParentStmt() == null) {
2906                                                if (!(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TCreateStageStmt)
2907                                                                && !(stmt instanceof TCreateExternalDataSourceStmt)
2908                                                                && !(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TMssqlDeclare)
2909                                                                && !(stmt instanceof TMssqlCreateFunction
2910                                                                                && ((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null)) {
2911                                                        boolean listen = false;
2912                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2913                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2914                                                                listen = true;
2915                                                        }
2916                                                        analyzeCustomSqlStmt(stmt);
2917                                                        if (listen && option.getHandleListener() != null) {
2918                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2919                                                        }
2920                                                }
2921                                        }
2922                                }
2923                        }
2924
2925                        if (option.getHandleListener() != null) {
2926                                option.getHandleListener().endAnalyzeDataFlow(sqlparser);
2927                        }
2928                } catch (Throwable e) {
2929                        logger.error("analyze sql failed.", e);
2930                        ErrorInfo errorInfo = new ErrorInfo();
2931                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
2932                        if (e.getMessage() == null) {
2933                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
2934                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
2935                                } else {
2936                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
2937                                }
2938                        } else {
2939                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
2940                        }
2941                        errorInfo.fillInfo(this);
2942                        errorInfos.add(errorInfo);
2943                }
2944                finally {
2945                        // Only restore old resolver state if TSQLResolver2 is not enabled
2946                        if (!TBaseType.isEnableResolver2()) {
2947                                TBaseType.setEnableResolver(OLD_ENABLE_RESOLVER);
2948                        }
2949                }
2950
2951        }
2952
2953        private boolean hasDb2ReturnStmt(TCreateFunctionStmt stmt) {
2954                if (stmt.getReturnStmt() != null) {
2955                        return true;
2956                }
2957                if (stmt.getBodyStatements() != null) {
2958                        for (int i = 0; i < stmt.getBodyStatements().size(); i++) {
2959                                if(stmt.getBodyStatements().get(i) instanceof TDb2ReturnStmt) {
2960                                        return true;
2961                                }
2962                        }
2963                }
2964                return false;
2965        }
2966
2967        private void analyzeCustomSqlStmt(TCustomSqlStatement stmt) {
2968                if (!accessedStatements.contains(stmt)) {
2969                        accessedStatements.add(stmt);
2970                } else if (!(stmt instanceof TUseDatabase || stmt instanceof TUseSchema)) {
2971                        return;
2972                }
2973
2974                ArrayList<TSyntaxError> errors = stmt.getSyntaxHints();
2975                if (errors != null && !errors.isEmpty()) {
2976                        for (int i = 0; i < errors.size(); i++) {
2977                                TSyntaxError error = errors.get(i);
2978                                ErrorInfo errorInfo = new ErrorInfo();
2979                                errorInfo.setErrorType(ErrorInfo.SYNTAX_HINT);
2980                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_HINT));
2981                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2982                                                ModelBindingManager.getGlobalHash()));
2983                                String[] segments = error.tokentext.split("\n");
2984                                if (segments.length == 1) {
2985                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2986                                                        error.columnNo + error.tokentext.length(), ModelBindingManager.getGlobalHash()));
2987                                } else {
2988                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2989                                                        (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash()));
2990                                }
2991                                errorInfo.fillInfo(this);
2992                                errorInfos.add(errorInfo);
2993                        }
2994                }
2995
2996                if (option.getAnalyzeMode() == AnalyzeMode.dynamic) {
2997                        if (!(stmt instanceof TStoredProcedureSqlStatement
2998                                        || stmt instanceof TExecuteSqlStatement
2999                                        || stmt instanceof TMssqlExecute
3000                                        || stmt instanceof TExecImmeStmt)) {
3001                                return;
3002                        }
3003                }
3004
3005                if(DlineageUtil.getTopStmt(stmt) == stmt){
3006                        modelManager.collectSqlHash(stmt);
3007                }
3008
3009                try {
3010                        if (stmt instanceof TUseDatabase) {
3011                                if (((TUseDatabase) stmt).getDatabaseName() != null) {
3012                                        ModelBindingManager.setGlobalDatabase(((TUseDatabase) stmt).getDatabaseName().toString());
3013                                }
3014                        } else if (stmt instanceof TUseSchema) {
3015                                if (((TUseSchema) stmt).getSchemaName() != null) {
3016                                        String schemaName = ((TUseSchema) stmt).getSchemaName().toString();
3017                                        List<String> splits = SQLUtil.parseNames(schemaName);
3018                                        if (splits.size() == 1) {
3019                                                ModelBindingManager.setGlobalSchema(schemaName);
3020                                        } else if (splits.size() > 1) {
3021                                                ModelBindingManager.setGlobalSchema(splits.get(splits.size() - 1));
3022                                                ModelBindingManager.setGlobalDatabase(splits.get(splits.size() - 2));
3023                                        }
3024                                }
3025                        } else if (stmt instanceof TPlsqlRecordTypeDefStmt) {
3026                                this.stmtStack.push(stmt);
3027                                this.analyzePlsqlRecordTypeDefStmt((TPlsqlRecordTypeDefStmt) stmt);
3028                                this.stmtStack.pop();
3029                        } else if (stmt instanceof TPlsqlTableTypeDefStmt) {
3030                                this.stmtStack.push(stmt);
3031                                this.analyzePlsqlTableTypeDefStmt((TPlsqlTableTypeDefStmt) stmt);
3032                                this.stmtStack.pop();
3033                        } else if (stmt instanceof TStoredProcedureSqlStatement) {
3034                                this.stmtStack.push(stmt);
3035                                this.analyzeStoredProcedureStmt((TStoredProcedureSqlStatement) stmt);
3036                                this.stmtStack.pop();
3037                        } else if (stmt instanceof TCreateTableSqlStatement) {
3038                                stmtStack.push(stmt);
3039                                analyzeCreateTableStmt((TCreateTableSqlStatement) stmt);
3040                                stmtStack.pop();
3041                        } else if (stmt instanceof TCreateStageStmt) {
3042                                stmtStack.push(stmt);
3043                                analyzeCreateStageStmt((TCreateStageStmt) stmt);
3044                                stmtStack.pop();
3045                        } else if (stmt instanceof TCreateExternalDataSourceStmt) {
3046                                stmtStack.push(stmt);
3047                                analyzeCreateExternalDataSourceStmt((TCreateExternalDataSourceStmt) stmt);
3048                                stmtStack.pop();
3049                        } else if (stmt instanceof TCreateStreamStmt) {
3050                                stmtStack.push(stmt);
3051                                analyzeCreateStreamStmt((TCreateStreamStmt) stmt);
3052                                stmtStack.pop();
3053                        } else if (stmt instanceof TSelectSqlStatement) {
3054                                analyzeSelectStmt((TSelectSqlStatement) stmt);
3055                        } else if (stmt instanceof TDropTableSqlStatement) {
3056                                stmtStack.push(stmt);
3057                                analyzeDropTableStmt((TDropTableSqlStatement) stmt);
3058                                stmtStack.pop();
3059                        } else if (stmt instanceof TTruncateStatement) {
3060                                stmtStack.push(stmt);
3061                                analyzeTruncateTableStmt((TTruncateStatement) stmt);
3062                                stmtStack.pop();
3063                        } else if (stmt instanceof TCreateMaterializedSqlStatement) {
3064                                stmtStack.push(stmt);
3065                                TCreateMaterializedSqlStatement view = (TCreateMaterializedSqlStatement) stmt;
3066                                analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName());
3067                                stmtStack.pop();
3068                        } else if (stmt instanceof TCreateViewSqlStatement) {
3069                                stmtStack.push(stmt);
3070                                TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt;
3071                                analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName());
3072                                stmtStack.pop();
3073                        } else if(stmt instanceof TDb2SqlVariableDeclaration){
3074                                stmtStack.push(stmt);
3075                                analyzeDb2Declare((TDb2SqlVariableDeclaration)stmt);
3076                                stmtStack.pop();
3077                        } else if (stmt instanceof TMssqlCreateType) {
3078                                stmtStack.push(stmt);
3079                                TMssqlCreateType createType = (TMssqlCreateType) stmt;
3080                                analyzeMssqlCreateType(createType);
3081                                stmtStack.pop();
3082                        } else if (stmt instanceof TMssqlDeclare) {
3083                                stmtStack.push(stmt);
3084                                TMssqlDeclare declare = (TMssqlDeclare) stmt;
3085                                analyzeMssqlDeclare(declare);
3086                                stmtStack.pop();
3087                        } else if (stmt instanceof TInsertSqlStatement) {
3088                                stmtStack.push(stmt);
3089                                TInsertSqlStatement insert = (TInsertSqlStatement)stmt;
3090                                analyzeInsertStmt(insert);
3091                                if(insert.getMultiInsertStatements()!=null) {
3092                                        for(int i=0;i<insert.getMultiInsertStatements().size();i++) {
3093                                                analyzeInsertStmt(insert.getMultiInsertStatements().get(i));
3094                                        }
3095                                }
3096                                stmtStack.pop();
3097                        } else if (stmt instanceof TRedshiftCopy) {
3098                                stmtStack.push(stmt);
3099                                analyzeRedshiftCopyStmt((TRedshiftCopy) stmt);
3100                                stmtStack.pop();
3101                        } else if (stmt instanceof TSnowflakeCopyIntoStmt) {
3102                                stmtStack.push(stmt);
3103                                analyzeCopyIntoStmt((TSnowflakeCopyIntoStmt) stmt);
3104                                stmtStack.pop();
3105                        } else if (stmt instanceof TUnloadStmt) {
3106                                stmtStack.push(stmt);
3107                                analyzeUnloadStmt((TUnloadStmt) stmt);
3108                                stmtStack.pop();
3109                        } else if (stmt instanceof TUpdateSqlStatement) {
3110                                stmtStack.push(stmt);
3111                                analyzeUpdateStmt((TUpdateSqlStatement) stmt);
3112                                stmtStack.pop();
3113                        } else if (stmt instanceof TMergeSqlStatement) {
3114                                stmtStack.push(stmt);
3115                                analyzeMergeStmt((TMergeSqlStatement) stmt);
3116                                stmtStack.pop();
3117                        } else if (stmt instanceof TDeleteSqlStatement) {
3118                                stmtStack.push(stmt);
3119                                analyzeDeleteStmt((TDeleteSqlStatement) stmt);
3120                                stmtStack.pop();
3121                        } else if (stmt instanceof TCursorDeclStmt) {
3122                                stmtStack.push(stmt);
3123                                analyzeCursorDeclStmt((TCursorDeclStmt) stmt);
3124                                stmtStack.pop();
3125                        } else if (stmt instanceof TFetchStmt) {
3126                                stmtStack.push(stmt);
3127                                analyzeFetchStmt((TFetchStmt) stmt);
3128                                stmtStack.pop();
3129                        } else if (stmt instanceof TMssqlFetch) {
3130                                stmtStack.push(stmt);
3131                                analyzeFetchStmt((TMssqlFetch) stmt);
3132                                stmtStack.pop();
3133                        } else if (stmt instanceof TForStmt) {
3134                                stmtStack.push(stmt);
3135                                analyzeForStmt((TForStmt) stmt);
3136                                stmtStack.pop();
3137                        } else if (stmt instanceof TOpenforStmt) {
3138                                stmtStack.push(stmt);
3139                                analyzeOpenForStmt((TOpenforStmt) stmt);
3140                                stmtStack.pop();
3141                        } else if (stmt instanceof TLoopStmt) {
3142                                stmtStack.push(stmt);
3143                                analyzeLoopStmt((TLoopStmt) stmt);
3144                                stmtStack.pop();
3145                        } else if (stmt instanceof TAssignStmt) {
3146                                stmtStack.push(stmt);
3147                                analyzeAssignStmt((TAssignStmt) stmt);
3148                                stmtStack.pop();
3149                        } else if (stmt instanceof TSetStmt) {
3150                                stmtStack.push(stmt);
3151                                analyzeSetStmt((TSetStmt) stmt);
3152                                stmtStack.pop();
3153                        } else if (stmt instanceof TMssqlSet) {
3154                                stmtStack.push(stmt);
3155                                analyzeMssqlSetStmt((TMssqlSet) stmt);
3156                                stmtStack.pop();
3157                        } else if (stmt instanceof TVarDeclStmt) {
3158                                stmtStack.push(stmt);
3159                                analyzeVarDeclStmt((TVarDeclStmt) stmt);
3160                                stmtStack.pop();
3161                        } else if (stmt instanceof TCreateDatabaseSqlStatement) {
3162                                stmtStack.push(stmt);
3163                                analyzeCloneDatabaseStmt((TCreateDatabaseSqlStatement) stmt);
3164                                stmtStack.pop();
3165                        } else if (stmt instanceof TCreateSchemaSqlStatement) {
3166                                stmtStack.push(stmt);
3167                                analyzeCloneSchemaStmt((TCreateSchemaSqlStatement) stmt);
3168                                stmtStack.pop();
3169                        } else if (stmt instanceof TAlterTableStatement) {
3170                                stmtStack.push(stmt);
3171                                analyzeAlterTableStmt((TAlterTableStatement) stmt);
3172                                stmtStack.pop();
3173                        } else if (stmt instanceof TRenameStmt) {
3174                                stmtStack.push(stmt);
3175                                analyzeRenameStmt((TRenameStmt) stmt);
3176                                stmtStack.pop();
3177                        } else if (stmt instanceof TCreateSynonymStmt) {
3178                                stmtStack.push(stmt);
3179                                analyzeCreateSynonymStmt((TCreateSynonymStmt) stmt);
3180                                stmtStack.pop();
3181                        } else if (stmt instanceof TLoadDataStmt) {
3182                                stmtStack.push(stmt);
3183                                analyzeLoadDataStmt((TLoadDataStmt) stmt);
3184                                stmtStack.pop();
3185                        } else if (stmt instanceof THiveLoad) {
3186                                stmtStack.push(stmt);
3187                                analyzeHiveLoadStmt((THiveLoad) stmt);
3188                                stmtStack.pop();
3189                        } else if (stmt instanceof TDb2ReturnStmt) {
3190                                stmtStack.push(stmt);
3191                                analyzeDb2ReturnStmt((TDb2ReturnStmt) stmt);
3192                                stmtStack.pop();
3193                        } else if (stmt instanceof TReturnStmt) {
3194                                stmtStack.push(stmt);
3195                                analyzeReturnStmt((TReturnStmt) stmt);
3196                                stmtStack.pop();
3197                        } else if (stmt instanceof TMssqlReturn) {
3198                                stmtStack.push(stmt);
3199                                analyzeMssqlReturnStmt((TMssqlReturn) stmt);
3200                                stmtStack.pop();
3201                        } else if (stmt instanceof TExecuteSqlStatement) {
3202                                String sqlText = ((TExecuteSqlStatement) stmt).getPreparedSqlText();
3203                                if(sqlText == null) {
3204                                        sqlText = ((TExecuteSqlStatement) stmt).getSqlText();
3205                                }
3206                                if (sqlText != null) {
3207                                        modelManager.collectDynamicSqlHash(stmt);
3208                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3209                                        sqlparser.sqltext = SQLUtil.trimColumnStringQuote(sqlText);
3210                                        int result = sqlparser.parse();
3211                                        if (result != 0) {
3212                                                errors = sqlparser.getSyntaxErrors();
3213                                                if (errors != null && !errors.isEmpty()) {
3214                                                        for (int i = 0; i < errors.size(); i++) {
3215                                                                TSyntaxError error = errors.get(i);
3216                                                                ErrorInfo errorInfo = new ErrorInfo();
3217                                                                errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
3218                                                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
3219                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
3220                                                                                ModelBindingManager.getGlobalHash()));
3221                                                                String[] segments = error.tokentext.split("\n");
3222                                                                if (segments.length == 1) {
3223                                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
3224                                                                                        error.columnNo + error.tokentext.length(),
3225                                                                                        ModelBindingManager.getGlobalHash()));
3226                                                                } else {
3227                                                                        errorInfo.setEndPosition(
3228                                                                                        new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
3229                                                                                                        (long) segments[segments.length - 1].length() + 1,
3230                                                                                                        ModelBindingManager.getGlobalHash()));
3231                                                                }
3232                                                                errorInfo.fillInfo(this);
3233                                                                errorInfos.add(errorInfo);
3234                                                        }
3235                                                }
3236                                        } else if (sqlparser.sqlstatements != null) {
3237                                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3238                                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3239                                                }
3240                                        }
3241                                }
3242                                else if (((TExecuteSqlStatement) stmt).getStmtString() != null) {
3243                                        modelManager.collectDynamicSqlHash(stmt);
3244                                }
3245                        } else if (stmt instanceof TMssqlExecute) {
3246                                TMssqlExecute executeStmt = (TMssqlExecute)stmt;
3247                                if (executeStmt.getSqlText() != null) {
3248                                        modelManager.collectDynamicSqlHash(stmt);
3249                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3250                                        sqlparser.sqltext = ((TMssqlExecute) stmt).getSqlText();
3251                                        int result = sqlparser.parse();
3252                                        if (result != 0) {
3253                                                errors = sqlparser.getSyntaxErrors();
3254                                                if (errors != null && !errors.isEmpty()) {
3255                                                        for (int i = 0; i < errors.size(); i++) {
3256                                                                TSyntaxError error = errors.get(i);
3257                                                                ErrorInfo errorInfo = new ErrorInfo();
3258                                                                errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
3259                                                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
3260                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
3261                                                                                ModelBindingManager.getGlobalHash()));
3262                                                                String[] segments = error.tokentext.split("\n");
3263                                                                if (segments.length == 1) {
3264                                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
3265                                                                                        error.columnNo + error.tokentext.length(),
3266                                                                                        ModelBindingManager.getGlobalHash()));
3267                                                                } else {
3268                                                                        errorInfo.setEndPosition(
3269                                                                                        new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
3270                                                                                                        (long) segments[segments.length - 1].length() + 1,
3271                                                                                                        ModelBindingManager.getGlobalHash()));
3272                                                                }
3273                                                                errorInfo.fillInfo(this);
3274                                                                errorInfos.add(errorInfo);
3275                                                        }
3276                                                }
3277                                        } else if (sqlparser.sqlstatements != null) {
3278                                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3279                                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3280                                                }
3281                                        }
3282                                } else if (executeStmt.getModuleName() != null) {
3283                                        stmtStack.push(stmt);
3284                                        analyzeMssqlExecute(executeStmt);
3285                                        stmtStack.pop();
3286                                }
3287                        } else if (stmt instanceof TExecImmeStmt) {
3288                                TExecImmeStmt execImmeStmt = (TExecImmeStmt) stmt;
3289                                modelManager.collectDynamicSqlHash(stmt);
3290                                synchronized (DataFlowAnalyzer.class) {
3291                                        TStatementList stmts = execImmeStmt.getDynamicStatements();
3292                                        if (stmts != null && stmts.size() > 0) {
3293                                                for (int i = 0; i < stmts.size(); i++) {
3294                                                        analyzeCustomSqlStmt(stmts.get(i));
3295                                                }
3296                                        }
3297
3298                                        String dynamicSql = execImmeStmt.getDynamicSQL();
3299                                        if (!SQLUtil.isEmpty(dynamicSql)) {
3300                                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3301                                                sqlparser.sqltext = dynamicSql;
3302                                                int result = sqlparser.parse();
3303                                                if (result != 0) {
3304                                                        errors = sqlparser.getSyntaxErrors();
3305                                                        if (errors != null && !errors.isEmpty()) {
3306                                                                for (int i = 0; i < errors.size(); i++) {
3307                                                                        TSyntaxError error = errors.get(i);
3308                                                                        ErrorInfo errorInfo = new ErrorInfo();
3309                                                                        errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
3310                                                                        errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
3311                                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
3312                                                                                        ModelBindingManager.getGlobalHash()));
3313                                                                        String[] segments = error.tokentext.split("\n");
3314                                                                        if (segments.length == 1) {
3315                                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
3316                                                                                                error.columnNo + error.tokentext.length(),
3317                                                                                                ModelBindingManager.getGlobalHash()));
3318                                                                        } else {
3319                                                                                errorInfo.setEndPosition(
3320                                                                                                new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
3321                                                                                                                (long) segments[segments.length - 1].length() + 1,
3322                                                                                                                ModelBindingManager.getGlobalHash()));
3323                                                                        }
3324                                                                        errorInfo.fillInfo(this);
3325                                                                        errorInfos.add(errorInfo);
3326                                                                }
3327                                                        }
3328                                                } else if (sqlparser.sqlstatements != null) {
3329                                                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3330                                                                analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3331                                                        }
3332                                                }
3333                                        }
3334                                }
3335                        } else if (stmt instanceof TCallStatement) {
3336                                TCallStatement callStmt = (TCallStatement)stmt;
3337                                stmtStack.push(stmt);
3338                                analyzeCallStmt(callStmt);
3339                                stmtStack.pop();
3340                        } else if (stmt instanceof TBasicStmt) {
3341                                TBasicStmt oracleBasicStmt = (TBasicStmt) stmt;
3342                                stmtStack.push(stmt);
3343                                analyzeOracleBasicStmt(oracleBasicStmt);
3344                                stmtStack.pop();
3345                        } else if (stmt instanceof TIfStmt) {
3346                                TIfStmt ifStmt = (TIfStmt) stmt;
3347                                stmtStack.push(stmt);
3348                                analyzeIfStmt(ifStmt);
3349                                stmtStack.pop();
3350                        } else if (stmt instanceof TElsifStmt) {
3351                                TElsifStmt elsIfStmt = (TElsifStmt) stmt;
3352                                stmtStack.push(stmt);
3353                                analyzeElsIfStmt(elsIfStmt);
3354                                stmtStack.pop();
3355                        } else if (stmt.getStatements() != null && stmt.getStatements().size() > 0) {
3356                                for (int i = 0; i < stmt.getStatements().size(); i++) {
3357                                        analyzeCustomSqlStmt(stmt.getStatements().get(i));
3358                                }
3359                        } else if (stmt instanceof TCreateIndexSqlStatement) {
3360                                stmtStack.push(stmt);
3361                                analyzeCreateIndexStageStmt((TCreateIndexSqlStatement) stmt);
3362                                stmtStack.pop();
3363                        }
3364                } catch (Exception e) {
3365                        logger.error("analyze sql stmt failed.", e);
3366                        ErrorInfo errorInfo = new ErrorInfo();
3367                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
3368                        if (e.getMessage() == null) {
3369                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
3370                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
3371                                } else {
3372                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
3373                                }
3374                        } else {
3375                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
3376                        }
3377                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
3378                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
3379                        String[] segments = stmt.getEndToken().getAstext().split("\n", -1);
3380                        if (segments.length == 1) {
3381                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
3382                                                stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
3383                                                ModelBindingManager.getGlobalHash()));
3384                        } else {
3385                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo + segments.length - 1,
3386                                                (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash()));
3387                        }
3388                        errorInfo.fillInfo(this);
3389                        errorInfos.add(errorInfo);
3390                }
3391        }
3392
3393        private void analyzePlsqlRecordTypeDefStmt(TPlsqlRecordTypeDefStmt stmt) {
3394                TObjectName typeName = stmt.getTypeName();
3395                Variable variable = modelFactory.createVariable(typeName);
3396                variable.setSubType(SubType.record_type);
3397        
3398                if (stmt.getFieldDeclarations() != null) {
3399                        for (int i = 0; i < stmt.getFieldDeclarations().size(); i++) {
3400                                TParameterDeclaration param = stmt.getFieldDeclarations().getParameterDeclarationItem(i);
3401                                String dataTypeName = param.getDataType().getDataTypeName();
3402                                TObjectName columnName = param.getParameterName();      
3403                                TableColumn variableProperty = modelFactory.createTableColumn(variable, columnName, true);
3404                                if(dataTypeName.indexOf(".")!=-1) {
3405                                        String tableName = dataTypeName.substring(0, dataTypeName.lastIndexOf("."));
3406                                        Table table = modelFactory.createTableByName(tableName, true);
3407                                        if(table!=null) {
3408                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(table, dataTypeName);
3409                                                if (tableColumn != null) {
3410                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3411                                                        relation.setEffectType(EffectType.rowtype);
3412                                                        relation.setTarget(new TableColumnRelationshipElement(variableProperty));
3413                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
3414                                                }
3415                                        }
3416                                }
3417                        }
3418                        variable.setDetermined(true);
3419                }
3420                else {
3421                        TObjectName starColumn = new TObjectName();
3422                        starColumn.setString("*");
3423                }
3424        }
3425        
3426        private void analyzePlsqlTableTypeDefStmt(TPlsqlTableTypeDefStmt stmt) {
3427                TTypeName typeName = stmt.getElementDataType();
3428                if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) {
3429                        Variable cursorVariable = modelFactory.createVariable(stmt.getTypeName());
3430                        cursorVariable.setSubType(SubType.record_type);
3431
3432                        Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false);
3433                        if(!variableTable.isCreateTable()) {
3434                                TObjectName starColumn1 = new TObjectName();
3435                                starColumn1.setString("*");
3436                                TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true);
3437                                variableTableStarColumn.setShowStar(false);
3438                                variableTableStarColumn.setExpandStar(true);
3439
3440                                TObjectName starColumn = new TObjectName();
3441                                starColumn.setString("*");
3442                                TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
3443                                variableProperty.setShowStar(false);
3444                                variableProperty.setExpandStar(true);
3445
3446                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3447                                dataflowRelation.setEffectType(EffectType.rowtype);
3448                                dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn));
3449                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
3450                        } else {
3451                                for (TableColumn sourceColumn : variableTable.getColumns()) {
3452                                        String columnName = sourceColumn.getName();
3453                                        TObjectName targetColumn = new TObjectName();
3454                                        targetColumn.setString(columnName);
3455                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true);
3456                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3457                                        dataflowRelation.setEffectType(EffectType.rowtype);
3458                                        dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn));
3459                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
3460                                }
3461                        }
3462                } 
3463        }
3464
3465        private void analyzeMssqlCreateType(TMssqlCreateType createType) {
3466
3467        }
3468
3469        private void analyzeMssqlExecute(TMssqlExecute executeStmt) {
3470                if (executeStmt.getModuleName() != null) {
3471                        TObjectName module = executeStmt.getModuleName();
3472                        if(module.toString().toLowerCase().endsWith("sp_rename")) {
3473                                String oldTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString());        
3474                                Table oldNameTableModel = modelFactory.createTableByName(oldTableName, true);
3475                                List<String> oldTableNames = SQLUtil.parseNames(oldNameTableModel.getName());
3476                                TObjectName oldStarColumn = new TObjectName();
3477                                oldStarColumn.setString("*");
3478                                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
3479                                
3480                                String newTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(1).toString());
3481                                List<String> newTableNames = SQLUtil.parseNames(newTableName);
3482                                if (oldTableNames.size() > newTableNames.size()) {
3483                                        for (int i = oldTableNames.size() - newTableNames.size() - 1; i >= 0; i--) {
3484                                                newTableName = (oldTableNames.get(i) + ".") + newTableName;
3485                                        }
3486                                }
3487
3488                                Table newNameTableModel = modelFactory.createTableByName(newTableName, true);
3489                                TObjectName newStarColumn = new TObjectName();
3490                                newStarColumn.setString("*");
3491                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true);
3492                                
3493                                Process process = modelFactory.createProcess(executeStmt);
3494                                newNameTableModel.addProcess(process);
3495                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3496                                relation.setEffectType(EffectType.rename_table);
3497                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
3498                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
3499                                relation.setProcess(process);
3500                                
3501                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
3502                                        oldTableStarColumn.setShowStar(false);
3503                                        relation.setShowStarRelation(false);
3504                                }
3505
3506                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
3507                                        newTableStarColumn.setShowStar(false);
3508                                        relation.setShowStarRelation(false);
3509                                }
3510                        }
3511                        else if(module.toString().toLowerCase().endsWith("sp_executesql")) {
3512                                String sql = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString()); 
3513                                if(sql.startsWith("N")) {
3514                                        sql =  SQLUtil.trimColumnStringQuote(sql.substring(1));
3515                                }
3516                                executeDynamicSql(sql);
3517                        }
3518                        else {
3519                                int argumentSize = executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size();
3520                                String procedureNameWithArgSize = module.toString() + "(" + argumentSize + ")";
3521                                if (argumentSize <= 0  || !DlineageUtil.supportFunctionOverride(option.getVendor())) {
3522                                        procedureNameWithArgSize = module.toString();
3523                                }
3524                                if (procedureDDLMap.containsKey(procedureNameWithArgSize)) {
3525                                        analyzeCustomSqlStmt(procedureDDLMap.get(procedureNameWithArgSize));
3526                                }
3527                                Procedure procedure = modelFactory.createProcedureByName(module, executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size());
3528                                String procedureParent = getProcedureParentName(executeStmt);
3529                                if (procedureParent != null) {
3530                                        Procedure caller = modelManager
3531                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3532                                        if (caller != null) {
3533                                                CallRelationship callRelation = modelFactory.createCallRelation();
3534                                                callRelation.setCallObject(executeStmt);
3535                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3536                                                callRelation.addSource(new ProcedureRelationshipElement(procedure));
3537                                                if(isBuiltInFunctionName(module) || isKeyword(module)){
3538                                                        callRelation.setBuiltIn(true);
3539                                                }
3540                                        }
3541                                }
3542
3543                                if (procedure.getArguments() != null) {
3544                                        for (int i = 0; i < procedure.getArguments().size(); i++) {
3545                                                Argument argument = procedure.getArguments().get(i);
3546                                                Variable variable = modelFactory.createVariable(procedure, argument.getName(), false);
3547                                                if (variable != null) {
3548                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3549                                                                Transform transform = new Transform();
3550                                                                transform.setType(Transform.FUNCTION);
3551                                                                transform.setCode(module);
3552                                                                variable.getColumns().get(0).setTransform(transform);
3553                                                        }
3554                                                        Process process = modelFactory.createProcess(executeStmt);
3555                                                        variable.addProcess(process);
3556                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), executeStmt, argument.getName(), i, process);
3557                                                }
3558                                        }
3559                                }
3560                        }
3561                }
3562        }
3563
3564        private void analyzeDropTableStmt(TDropTableSqlStatement stmt) {
3565                TTable dropTable = stmt.getTargetTable();
3566                if(dropTable == null) {
3567                        return;
3568                }
3569                Table tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(dropTable.getTableName().toString()));
3570                if(tableModel!=null) {
3571                        modelManager.dropTable(tableModel);
3572                }
3573                
3574                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
3575                        tableModel = modelFactory.createTable(dropTable);
3576                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
3577                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
3578                        crudRelationship.setEffectType(EffectType.drop_table);
3579                }
3580        }
3581        
3582        private void analyzeTruncateTableStmt(TTruncateStatement stmt) {
3583                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
3584                        TObjectName table = stmt.getTableName();
3585                        Table tableModel = modelFactory.createTableByName(table);
3586                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
3587                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
3588                        crudRelationship.setEffectType(EffectType.truncate_table);
3589                }
3590        }
3591
3592        private void analyzeCallStmt(TCallStatement callStmt) {
3593                if (callStmt.getRoutineExpr() != null && callStmt.getRoutineExpr().getFunctionCall() != null) {
3594
3595                        TFunctionCall functionCall = callStmt.getRoutineExpr().getFunctionCall();
3596                        Procedure callee = modelManager.getProcedureByName(
3597                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3598                        if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3599                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3600                                callee = modelManager.getProcedureByName(DlineageUtil
3601                                                .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3602                        }
3603                        if (callee != null) {
3604                                String procedureParent = getProcedureParentName(callStmt);
3605                                if (procedureParent != null) {
3606                                        Procedure caller = modelManager
3607                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3608                                        if (caller != null) {
3609                                                CallRelationship callRelation = modelFactory.createCallRelation();
3610                                                callRelation.setCallObject(callStmt);
3611                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3612                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3613                                                if (isBuiltInFunctionName(functionCall.getFunctionName())
3614                                                                || isKeyword(functionCall.getFunctionName())) {
3615                                                        callRelation.setBuiltIn(true);
3616                                                }
3617                                        }
3618                                }
3619                                if (callee.getArguments() != null) {
3620                                        for (int i = 0; i < callee.getArguments().size(); i++) {
3621                                                Argument argument = callee.getArguments().get(i);
3622                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3623                                                if (variable != null) {
3624                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3625                                                                Transform transform = new Transform();
3626                                                                transform.setType(Transform.FUNCTION);
3627                                                                transform.setCode(functionCall);
3628                                                                variable.getColumns().get(0).setTransform(transform);
3629                                                        }
3630                                                        Process process = modelFactory.createProcess(callStmt);
3631                                                        variable.addProcess(process);
3632                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i,
3633                                                                        process);
3634                                                }
3635                                        }
3636                                }
3637                        } else {
3638                                Function function = (Function) createFunction(functionCall);
3639                                String procedureParent = getProcedureParentName(callStmt);
3640                                if (procedureParent != null) {
3641                                        Procedure caller = modelManager
3642                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3643                                        if (caller != null) {
3644                                                CallRelationship callRelation = modelFactory.createCallRelation();
3645                                                callRelation.setCallObject(callStmt);
3646                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3647                                                callRelation.addSource(new FunctionRelationshipElement(function));
3648                                                if (isBuiltInFunctionName(functionCall.getFunctionName())
3649                                                                || isKeyword(functionCall.getFunctionName())) {
3650                                                        callRelation.setBuiltIn(true);
3651                                                }
3652                                        }
3653                                }
3654                        }
3655                }
3656                else if (callStmt.getRoutineName() != null) {
3657                        TObjectName function = callStmt.getRoutineName();
3658                        String functionName = function.toString();
3659                        Procedure callee = modelManager.getProcedureByName(
3660                                        DlineageUtil.getIdentifierNormalTableName(functionName));
3661                        if (callee == null && procedureDDLMap.containsKey(functionName)) {
3662                                analyzeCustomSqlStmt(procedureDDLMap.get(functionName));
3663                                callee = modelManager.getProcedureByName(functionName);
3664                        }
3665                        if (callee != null) {
3666                                String procedureParent = getProcedureParentName(callStmt);
3667                                if (procedureParent != null) {
3668                                        Procedure caller = modelManager
3669                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3670                                        if (caller != null) {
3671                                                CallRelationship callRelation = modelFactory.createCallRelation();
3672                                                callRelation.setCallObject(callStmt);
3673                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3674                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3675                                                if (isBuiltInFunctionName(function)
3676                                                                || isKeyword(function)) {
3677                                                        callRelation.setBuiltIn(true);
3678                                                }
3679                                        }
3680                                }
3681                                if (callee.getArguments() != null) {
3682                                        for (int i = 0; i < callee.getArguments().size(); i++) {
3683                                                Argument argument = callee.getArguments().get(i);
3684                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3685                                                if (variable != null) {
3686                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3687                                                                Transform transform = new Transform();
3688                                                                transform.setType(Transform.FUNCTION);
3689                                                                transform.setCode(callStmt);
3690                                                                variable.getColumns().get(0).setTransform(transform);
3691                                                        }
3692                                                        Process process = modelFactory.createProcess(callStmt);
3693                                                        variable.addProcess(process);
3694                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), callStmt, i,
3695                                                                        process);
3696                                                }
3697                                        }
3698                                }
3699                        }
3700                }
3701        }
3702
3703        private boolean analyzeCustomFunctionCall(TFunctionCall functionCall) {
3704                Procedure callee = modelManager.getProcedureByName(
3705                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3706                if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3707                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3708                        callee = modelManager.getProcedureByName(
3709                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3710                }
3711                if (callee != null) {
3712                        String procedureParent = getProcedureParentName(stmtStack.peek());
3713                        if (procedureParent != null) {
3714                                Procedure caller = modelManager
3715                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3716                                if (caller != null) {
3717                                        CallRelationship callRelation = modelFactory.createCallRelation();
3718                                        callRelation.setCallObject(functionCall);
3719                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3720                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
3721                                        if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3722                                                callRelation.setBuiltIn(true);
3723                                        }
3724                                }
3725                        }
3726                        if (callee.getArguments() != null) {
3727                                for (int i = 0; i < callee.getArguments().size(); i++) {
3728                                        Argument argument = callee.getArguments().get(i);
3729                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3730                                        if(variable!=null) {
3731                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3732                                                        Transform transform = new Transform();
3733                                                        transform.setType(Transform.FUNCTION);
3734                                                        transform.setCode(functionCall);
3735                                                        variable.getColumns().get(0).setTransform(transform);
3736                                                }
3737                                                Process process = modelFactory.createProcess(functionCall);
3738                                                variable.addProcess(process);
3739                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process);
3740                                        }
3741                                }
3742                        }
3743                        return true;
3744                }
3745                return false;
3746        }
3747
3748        private void analyzeOracleBasicStmt(TBasicStmt oracleBasicStmt) {
3749                if (oracleBasicStmt.getExpr() == null || oracleBasicStmt.getExpr().getFunctionCall() == null) {
3750                        return;
3751                }
3752
3753                TFunctionCall functionCall = oracleBasicStmt.getExpr().getFunctionCall();
3754                Procedure callee = modelManager.getProcedureByName(
3755                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3756                if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3757                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3758                        callee = modelManager.getProcedureByName(
3759                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3760                }
3761                if (callee != null) {
3762                        String procedureParent = getProcedureParentName(oracleBasicStmt);
3763                        if (procedureParent != null) {
3764                                Procedure caller = modelManager
3765                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3766                                if (caller != null) {
3767                                        CallRelationship callRelation = modelFactory.createCallRelation();
3768                                        callRelation.setCallObject(functionCall);
3769                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3770                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
3771                                        if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString())
3772                                                        || (isBuiltInFunctionName(functionCall.getFunctionName())
3773                                                        || isKeyword(functionCall.getFunctionName()))) {
3774                                                callRelation.setBuiltIn(true);
3775                                        }
3776                                }
3777                        }
3778                        if (callee.getArguments() != null) {
3779                                for (int i = 0; i < callee.getArguments().size(); i++) {
3780                                        Argument argument = callee.getArguments().get(i);
3781                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3782                                        if(variable!=null) {
3783                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3784                                                        Transform transform = new Transform();
3785                                                        transform.setType(Transform.FUNCTION);
3786                                                        transform.setCode(functionCall);
3787                                                        variable.getColumns().get(0).setTransform(transform);
3788                                                }
3789                                                Process process = modelFactory.createProcess(functionCall);
3790                                                variable.addProcess(process);
3791                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process);
3792                                        }
3793                                }
3794                        }
3795                } else {
3796                        Function function = modelFactory.createFunction(functionCall);
3797                        String procedureParent = getProcedureParentName(oracleBasicStmt);
3798                        if (procedureParent != null) {
3799                                Procedure caller = modelManager
3800                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3801                                if (caller != null) {
3802                                        CallRelationship callRelation = modelFactory.createCallRelation();
3803                                        callRelation.setCallObject(functionCall);
3804                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3805                                        callRelation.addSource(new FunctionRelationshipElement(function));
3806                                        if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString())
3807                                                        || (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName()))) {
3808                                                callRelation.setBuiltIn(true);
3809                                        }
3810                                }
3811                        }
3812                }
3813        }
3814
3815        private void analyzeIfStmt(TIfStmt ifStmt) {
3816                if (ifStmt.getCondition() != null) {
3817                        columnsInExpr visitor = new columnsInExpr();
3818                        ifStmt.getCondition().inOrderTraverse(visitor);
3819                        List<TParseTreeNode> functions = visitor.getFunctions();
3820
3821                        if (functions != null && !functions.isEmpty()) {
3822                                for (int i = 0; i < functions.size(); i++) {
3823                                        if (!(functions.get(i) instanceof TFunctionCall))
3824                                                continue;
3825                                        TFunctionCall functionCall = (TFunctionCall) functions.get(i);
3826                                        Procedure callee = modelManager.getProcedureByName(DlineageUtil
3827                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3828                                        if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3829                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3830                                                callee = modelManager.getProcedureByName(
3831                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3832                                        }
3833                                        if (callee != null) {
3834                                                String procedureParent = getProcedureParentName(ifStmt);
3835                                                if (procedureParent != null) {
3836                                                        Procedure caller = modelManager
3837                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3838                                                        if (caller != null) {
3839                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3840                                                                callRelation.setCallObject(functionCall);
3841                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3842                                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3843                                                                if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) {
3844                                                                        callRelation.setBuiltIn(true);
3845                                                                }
3846                                                        }
3847                                                }
3848                                                if (callee.getArguments() != null) {
3849                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
3850                                                                Argument argument = callee.getArguments().get(j);
3851                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3852                                                                if(variable!=null) {
3853                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3854                                                                                Transform transform = new Transform();
3855                                                                                transform.setType(Transform.FUNCTION);
3856                                                                                transform.setCode(functionCall);
3857                                                                                variable.getColumns().get(0).setTransform(transform);
3858                                                                        }
3859                                                                        Process process = modelFactory.createProcess(functionCall);
3860                                                                        variable.addProcess(process);
3861                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
3862                                                                }
3863                                                        }
3864                                                }
3865                                        } else {
3866                                                Function function = modelFactory.createFunction(functionCall);
3867                                                String procedureParent = getProcedureParentName(ifStmt);
3868                                                if (procedureParent != null) {
3869                                                        Procedure caller = modelManager
3870                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3871                                                        if (caller != null) {
3872                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3873                                                                callRelation.setCallObject(functionCall);
3874                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3875                                                                callRelation.addSource(new FunctionRelationshipElement(function));
3876                                                                if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) {
3877                                                                        callRelation.setBuiltIn(true);
3878                                                                }
3879                                                        }
3880                                                }
3881                                        }
3882                                }
3883                        }
3884                }
3885
3886                if (ifStmt.getThenStatements() != null) {
3887                        for (int i = 0; i < ifStmt.getThenStatements().size(); ++i) {
3888                                analyzeCustomSqlStmt(ifStmt.getThenStatements().get(i));
3889                                ResultSet returnResult = modelFactory.createResultSet(ifStmt.getThenStatements().get(i), false);
3890                                if(returnResult!=null){
3891                                        for(ResultColumn resultColumn: returnResult.getColumns()){
3892                                                analyzeFilterCondition(resultColumn, ifStmt.getCondition(), null, null, EffectType.function);
3893                                        }
3894                                }
3895                        }
3896                }
3897
3898                if (ifStmt.getElseifStatements() != null) {
3899                        for (int i = 0; i < ifStmt.getElseifStatements().size(); ++i) {
3900                                analyzeCustomSqlStmt(ifStmt.getElseifStatements().get(i));
3901                        }
3902                }
3903
3904                if (ifStmt.getElseStatements() != null) {
3905                        for (int i = 0; i < ifStmt.getElseStatements().size(); ++i) {
3906                                analyzeCustomSqlStmt(ifStmt.getElseStatements().get(i));
3907                        }
3908                }
3909        }
3910
3911        private void analyzeElsIfStmt(TElsifStmt elsIfStmt) {
3912                if (elsIfStmt.getCondition() != null) {
3913                        columnsInExpr visitor = new columnsInExpr();
3914                        elsIfStmt.getCondition().inOrderTraverse(visitor);
3915                        List<TParseTreeNode> functions = visitor.getFunctions();
3916
3917                        if (functions != null && !functions.isEmpty()) {
3918                                for (int i = 0; i < functions.size(); i++) {
3919                                        if (!(functions.get(i) instanceof TFunctionCall))
3920                                                continue;
3921                                        TFunctionCall functionCall = (TFunctionCall) functions.get(i);
3922                                        Procedure callee = modelManager.getProcedureByName(DlineageUtil
3923                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3924                                        if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3925                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3926                                                callee = modelManager.getProcedureByName(
3927                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3928                                        }
3929                                        if (callee != null) {
3930                                                String procedureParent = getProcedureParentName(elsIfStmt);
3931                                                if (procedureParent != null) {
3932                                                        Procedure caller = modelManager
3933                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3934                                                        if (caller != null) {
3935                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3936                                                                callRelation.setCallObject(functionCall);
3937                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3938                                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3939                                                                if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3940                                                                        callRelation.setBuiltIn(true);
3941                                                                }
3942                                                        }
3943                                                }
3944                                                if (callee.getArguments() != null) {
3945                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
3946                                                                Argument argument = callee.getArguments().get(j);
3947                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3948                                                                if(variable!=null) {
3949                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3950                                                                                Transform transform = new Transform();
3951                                                                                transform.setType(Transform.FUNCTION);
3952                                                                                transform.setCode(functionCall);
3953                                                                                variable.getColumns().get(0).setTransform(transform);
3954                                                                        }
3955                                                                        Process process = modelFactory.createProcess(functionCall);
3956                                                                        variable.addProcess(process);
3957                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
3958                                                                }
3959                                                        }
3960                                                }
3961                                        } else {
3962                                                Function function = modelFactory.createFunction(functionCall);
3963                                                String procedureParent = getProcedureParentName(elsIfStmt);
3964                                                if (procedureParent != null) {
3965                                                        Procedure caller = modelManager
3966                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3967                                                        if (caller != null) {
3968                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3969                                                                callRelation.setCallObject(functionCall);
3970                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3971                                                                callRelation.addSource(new FunctionRelationshipElement(function));
3972                                                                if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3973                                                                        callRelation.setBuiltIn(true);
3974                                                                }
3975                                                        }
3976                                                }
3977                                        }
3978                                }
3979                        }
3980                }
3981
3982                if (elsIfStmt.getThenStatements() != null) {
3983                        for (int i = 0; i < elsIfStmt.getThenStatements().size(); ++i) {
3984                                ResultSet returnResult = modelFactory.createResultSet(elsIfStmt.getThenStatements().get(i), false);
3985                                if (returnResult != null) {
3986                                        for (ResultColumn resultColumn : returnResult.getColumns()) {
3987                                                analyzeFilterCondition(resultColumn, elsIfStmt.getCondition(), null, null, EffectType.function);
3988                                        }
3989                                }
3990                                analyzeCustomSqlStmt(elsIfStmt.getThenStatements().get(i));
3991                        }
3992                }
3993        }
3994
3995        private void analyzeCloneTableStmt(TCreateTableSqlStatement stmt) {
3996                if (stmt.getCloneSourceTable() != null) {
3997                        Table sourceTable = modelFactory.createTableByName(stmt.getCloneSourceTable());
3998                        Table cloneTable = modelFactory.createTableByName(stmt.getTableName());
3999                        Process process = modelFactory.createProcess(stmt);
4000                        cloneTable.addProcess(process);
4001
4002                        if (sourceTable.isDetermined()) {
4003                                for (int k = 0; k < sourceTable.getColumns().size(); k++) {
4004                                        TableColumn sourceColumn = sourceTable.getColumns().get(k);
4005                                        TObjectName objectName = new TObjectName();
4006                                        objectName.setString(sourceColumn.getName());
4007                                        TableColumn tableColumn = modelFactory.createTableColumn(cloneTable, objectName, true);
4008                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4009                                        dataflowRelation.setEffectType(EffectType.clone_table);
4010                                        dataflowRelation
4011                                                        .addSource(new TableColumnRelationshipElement(sourceColumn));
4012                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
4013                                        dataflowRelation.setProcess(process);
4014                                }
4015                                cloneTable.setDetermined(true);
4016                                cloneTable.setFromDDL(true);
4017                        } else {
4018                                TObjectName sourceName = new TObjectName();
4019                                sourceName.setString("*");
4020                                TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceName, false);
4021                                TObjectName targetName = new TObjectName();
4022                                targetName.setString("*");
4023                                TableColumn targetTableColumn = modelFactory.createTableColumn(cloneTable, targetName, false);
4024                                if(sourceTableColumn!=null && targetTableColumn!=null) {
4025                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4026                                        dataflowRelation.setEffectType(EffectType.clone_table);
4027                                        dataflowRelation
4028                                                        .addSource(new TableColumnRelationshipElement(sourceTableColumn));
4029                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
4030                                        dataflowRelation.setProcess(process);
4031                                }
4032                        }
4033                }
4034        }
4035
4036        private void analyzeCloneDatabaseStmt(TCreateDatabaseSqlStatement stmt) {
4037                if (stmt.getCloneSourceDb() != null) {
4038                        Database sourceDatabase = modelFactory.createDatabase(stmt.getCloneSourceDb());
4039                        Database cloneDatabase = modelFactory.createDatabase(stmt.getDatabaseName());
4040                        Process process = modelFactory.createProcess(stmt);
4041                        cloneDatabase.addProcess(process);
4042                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4043                        relation.setEffectType(EffectType.clone_database);
4044                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneDatabase.getRelationRows()));
4045                        relation.addSource(
4046                                        new RelationRowsRelationshipElement<TableRelationRows>(sourceDatabase.getRelationRows()));
4047                        relation.setProcess(process);
4048                }
4049        }
4050
4051        private void analyzeCloneSchemaStmt(TCreateSchemaSqlStatement stmt) {
4052                if (stmt.getCloneSourceSchema() != null) {
4053                        Schema sourceSchema = modelFactory.createSchema(stmt.getCloneSourceSchema());
4054                        Schema cloneSchema = modelFactory.createSchema(stmt.getSchemaName());
4055                        Process process = modelFactory.createProcess(stmt);
4056                        cloneSchema.addProcess(process);
4057                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4058                        relation.setEffectType(EffectType.clone_schema);
4059                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneSchema.getRelationRows()));
4060                        relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(sourceSchema.getRelationRows()));
4061                        relation.setProcess(process);
4062                }
4063        }
4064
4065        private void executeDynamicSql(String sql) {
4066                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
4067                sqlparser.sqltext = sql;
4068                int result = sqlparser.parse();
4069                if (result == 0) {
4070                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
4071                                analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
4072                        }
4073                }
4074        }
4075
4076        private void extractSnowflakeSQLFromProcedure(TCreateProcedureStmt procedure) {
4077                Map<String, String> argMap = new LinkedHashMap<String, String>();
4078                if (procedure.getParameterDeclarations() != null) {
4079                        for (int i = 0; i < procedure.getParameterDeclarations().size(); i++) {
4080                                TParameterDeclaration def = procedure.getParameterDeclarations().getParameterDeclarationItem(i);
4081                                argMap.put(def.getParameterName().toString(), def.getDataType().getDataTypeName());
4082                        }
4083                }
4084                StringBuilder buffer = new StringBuilder();
4085                buffer.append("(function(");
4086                String[] args = argMap.keySet().toArray(new String[0]);
4087                for (int i = 0; i < args.length; i++) {
4088                        buffer.append(args[i].toUpperCase());
4089                        if (i < args.length - 1) {
4090                                buffer.append(",");
4091                        }
4092                }
4093                buffer.append("){\n");
4094
4095                int start = -1;
4096                int end = -1;
4097                boolean dollar = false;
4098                boolean quote = false;
4099                if (procedure.getRoutineBody().indexOf("$$") != -1) {
4100                        start = procedure.getRoutineBody().indexOf("$$") + 2;
4101                        end = procedure.getRoutineBody().lastIndexOf("$$") - 1;
4102                        dollar = true;
4103                } else if (procedure.getRoutineBody().indexOf("'") != -1) {
4104                        start = procedure.getRoutineBody().indexOf("'") + 1;
4105                        end = procedure.getRoutineBody().lastIndexOf("'");
4106                        quote = true;
4107                }
4108                String body = procedure.getRoutineBody().substring(start, end);
4109                if (dollar && body.indexOf("`") != -1) {
4110                        Pattern pattern = Pattern.compile("`.+?`", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
4111                        Matcher matcher = pattern.matcher(body);
4112                        StringBuffer replaceBuffer = new StringBuffer();
4113                        while (matcher.find()) {
4114                                String condition = matcher.group().replace("\r\n", "\n").replace("'", "\\\\'")
4115                                                .replace("\n", "\\\\n'\n+'").replace("`", "'").replace("$", "RDS_CHAR_DOLLAR");
4116                                matcher.appendReplacement(replaceBuffer, condition);
4117                        }
4118                        matcher.appendTail(replaceBuffer);
4119                        body = replaceBuffer.toString().replace("RDS_CHAR_DOLLAR", "$");
4120                }
4121                if (quote && body.indexOf("'") != -1) {
4122                        body = body.replace("''", "'");
4123                }
4124                buffer.append(body);
4125                buffer.append("})(");
4126                for (int i = 0; i < args.length; i++) {
4127                        String type = argMap.get(args[i]);
4128                        if (type.equalsIgnoreCase("VARCHAR")) {
4129                                buffer.append("'pseudo'");
4130                        } else if (type.equalsIgnoreCase("STRING")) {
4131                                buffer.append("'pseudo'");
4132                        } else if (type.equalsIgnoreCase("CHAR")) {
4133                                buffer.append("'pseudo'");
4134                        } else if (type.equalsIgnoreCase("CHARACTER")) {
4135                                buffer.append("'pseudo'");
4136                        } else if (type.equalsIgnoreCase("TEXT")) {
4137                                buffer.append("'pseudo'");
4138                        } else if (type.equalsIgnoreCase("BINARY")) {
4139                                buffer.append("'pseudo'");
4140                        } else if (type.equalsIgnoreCase("VARBINARY")) {
4141                                buffer.append("'pseudo'");
4142                        } else if (type.equalsIgnoreCase("BOOLEAN")) {
4143                                buffer.append(true);
4144                        } else if (type.equalsIgnoreCase("FLOAT")) {
4145                                buffer.append("1.0");
4146                        } else if (type.equalsIgnoreCase("FLOAT4")) {
4147                                buffer.append("1.0");
4148                        } else if (type.equalsIgnoreCase("FLOAT8")) {
4149                                buffer.append("1.0");
4150                        } else if (type.equalsIgnoreCase("DOUBLE")) {
4151                                buffer.append("1.0");
4152                        } else if (type.equalsIgnoreCase("DOUBLE PRECISION")) {
4153                                buffer.append("1.0");
4154                        } else if (type.equalsIgnoreCase("REAL")) {
4155                                buffer.append("1.0");
4156                        } else if (type.equalsIgnoreCase("NUMBER")) {
4157                                buffer.append("1.0");
4158                        } else if (type.equalsIgnoreCase("DECIMAL")) {
4159                                buffer.append("1.0");
4160                        } else if (type.equalsIgnoreCase("NUMERIC")) {
4161                                buffer.append("1.0");
4162                        } else if (type.equalsIgnoreCase("INT")) {
4163                                buffer.append("1");
4164                        } else if (type.equalsIgnoreCase("INTEGER")) {
4165                                buffer.append("1");
4166                        } else if (type.equalsIgnoreCase("BIGINT")) {
4167                                buffer.append("1");
4168                        } else if (type.equalsIgnoreCase("SMALLINT")) {
4169                                buffer.append("1");
4170                        } else if (type.equalsIgnoreCase("DATE")) {
4171                                buffer.append("new Date()");
4172                        } else if (type.equalsIgnoreCase("DATETIME")) {
4173                                buffer.append("new Date()");
4174                        } else if (type.equalsIgnoreCase("TIME")) {
4175                                buffer.append("new Date()");
4176                        } else if (type.equalsIgnoreCase("TIMESTAMP")) {
4177                                buffer.append("new Date()");
4178                        } else if (type.equalsIgnoreCase("TIMESTAMP_LTZ")) {
4179                                buffer.append("new Date()");
4180                        } else if (type.equalsIgnoreCase("TIMESTAMP_NTZ")) {
4181                                buffer.append("new Date()");
4182                        } else if (type.equalsIgnoreCase("TIMESTAMP_TZ")) {
4183                                buffer.append("new Date()");
4184                        } else if (type.equalsIgnoreCase("VARIANT")) {
4185                                buffer.append("{}");
4186                        } else if (type.equalsIgnoreCase("OBJECT")) {
4187                                buffer.append("{}");
4188                        } else if (type.equalsIgnoreCase("ARRAY")) {
4189                                buffer.append("[]");
4190                        } else if (type.equalsIgnoreCase("GEOGRAPHY")) {
4191                                buffer.append("{}");
4192                        }
4193                        if (i < args.length - 1) {
4194                                buffer.append(",");
4195                        }
4196                }
4197                buffer.append(");");
4198
4199                try {
4200                        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
4201                        ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
4202                        nashorn.put("analyzer", this);
4203                        nashorn.eval(new InputStreamReader(
4204                                        getClass().getResourceAsStream("/gudusoft/gsqlparser/parser/snowflake/snowflake.js")));
4205                        nashorn.eval(new StringReader(buffer.toString()));
4206                } catch (ScriptException e) {
4207                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
4208                        sqlparser.sqltext = body;
4209                        int result = sqlparser.parse();
4210                        if (result == 0) {
4211                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
4212                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
4213                                }
4214                                return;
4215                        }
4216                        ErrorInfo errorInfo = new ErrorInfo();
4217                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
4218                        errorInfo.setErrorMessage("Invoke script error: " + e.getMessage());
4219                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(procedure.getStartToken().lineNo,
4220                                        procedure.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
4221                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(procedure.getEndToken().lineNo,
4222                                        procedure.getEndToken().columnNo + procedure.getEndToken().getAstext().length(),
4223                                        ModelBindingManager.getGlobalHash()));
4224                        errorInfos.add(errorInfo);
4225                }
4226        }
4227
4228        private void analyzeHiveLoadStmt(THiveLoad stmt) {
4229                if (stmt.getPath() != null && stmt.getTable() != null) {
4230                        Table uriFile = modelFactory.createTableByName(stmt.getPath(), true);
4231                        uriFile.setPath(true);
4232                        uriFile.setCreateTable(true);
4233                        TObjectName fileUri = new TObjectName();
4234                        fileUri.setString("uri=" + stmt.getPath());
4235                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
4236
4237                        Table tableModel = modelFactory.createTable(stmt.getTable());
4238                        Process process = modelFactory.createProcess(stmt);
4239                        tableModel.addProcess(process);
4240
4241                        TPartitionExtensionClause p = stmt.getTable().getPartitionExtensionClause();
4242                        if (p.getKeyValues() != null && p.getKeyValues().size() > 0) {
4243                                for (int i = 0; i < p.getKeyValues().size(); i++) {
4244                                        TExpression expression = p.getKeyValues().getExpression(i);
4245                                        if (expression.getLeftOperand().getExpressionType() == EExpressionType.simple_object_name_t) {
4246                                                modelFactory.createTableColumn(tableModel, expression.getLeftOperand().getObjectOperand(),
4247                                                                true);
4248                                        }
4249                                }
4250                        }
4251
4252                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
4253                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4254                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4255                                relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
4256                                relation.setProcess(process);
4257                        }
4258                }
4259        }
4260        
4261        private void analyzeLoadDataStmt(TLoadDataStmt stmt) {
4262                
4263        }
4264
4265        private void analyzeUnloadStmt(TUnloadStmt unloadStmt) {
4266                if (unloadStmt.getSelectSqlStatement() != null && unloadStmt.getS3() != null) {
4267
4268                        Table uriFile = modelFactory.createTableByName(unloadStmt.getS3(), true);
4269                        uriFile.setPath(true);
4270                        uriFile.setCreateTable(true);
4271                        TObjectName fileUri = new TObjectName();
4272                        fileUri.setString("uri=" + unloadStmt.getS3());
4273                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
4274
4275                        Process process = modelFactory.createProcess(unloadStmt);
4276                        uriFile.addProcess(process);
4277
4278                        TCustomSqlStatement stmt = unloadStmt.getSelectSqlStatement();
4279                        analyzeCustomSqlStmt(stmt);
4280                        if (stmt instanceof TSelectSqlStatement) {
4281                                TSelectSqlStatement select = (TSelectSqlStatement) stmt;
4282                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(select);
4283                                if (resultSetModel != null) {
4284                                        for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
4285                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
4286                                                if (resultColumn.hasStarLinkColumn()
4287                                                                && resultColumn.getStarLinkColumnNames().size() > 0) {
4288                                                        for (int k = 0; k < resultColumn.getStarLinkColumnNames().size(); k++) {
4289                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(resultSetModel,
4290                                                                                resultColumn.getStarLinkColumnName(k), false);
4291                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4292                                                                dataflowRelation.setEffectType(EffectType.unload);
4293                                                                dataflowRelation
4294                                                                                .addSource(new ResultColumnRelationshipElement(expandStarColumn));
4295                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn));
4296                                                                dataflowRelation.setProcess(process);
4297                                                        }
4298                                                }
4299                                                if (!resultColumn.hasStarLinkColumn() || resultColumn.isShowStar()) {
4300                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4301                                                        dataflowRelation.setEffectType(EffectType.unload);
4302                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
4303                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn));
4304                                                        dataflowRelation.setProcess(process);
4305                                                }
4306                                        }
4307                                }
4308                        }
4309                }
4310
4311        }
4312
4313        private void analyzeCopyIntoStmt(TSnowflakeCopyIntoStmt stmt) {
4314                if (stmt.getTableName() != null) {
4315                        if (stmt.getStageLocation() != null) {
4316                                Table intoTable = modelManager
4317                                                .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
4318                                if (intoTable == null) {
4319                                        intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
4320                                        TObjectName starColumn = new TObjectName();
4321                                        starColumn.setString("*");
4322                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
4323                                        if (column != null) {
4324                                                column.setExpandStar(false);
4325                                                column.setPseduo(true);
4326                                        }
4327                                }
4328                                Process process = modelFactory.createProcess(stmt);
4329                                intoTable.addProcess(process);
4330
4331                                TObjectName stageName = stmt.getStageLocation().getStageName();
4332                                if (stageName == null || stmt.getStageLocation().getTableName() != null) {
4333                                        stageName = stmt.getStageLocation().getTableName();
4334                                }
4335                                if (stageName != null) {
4336                                        String stageFullName = DlineageUtil.getTableFullName(stageName.toString());
4337                                        Table stage = modelManager.getTableByName(stageFullName);
4338                                        if (stage == null) {
4339                                                stage = modelFactory.createStage(stageName);
4340                                                stage.setCreateTable(true);
4341                                                stage.setStage(true);
4342                                                if (stmt.getStageLocation().getPath() != null) {
4343                                                        stage.setLocation(stmt.getStageLocation().getPath().toString());
4344                                                        TObjectName location = new TObjectName();
4345                                                        location.setString(stmt.getStageLocation().getPath().toString());
4346                                                        modelFactory.createStageLocation(stage, location);
4347                                                } else {
4348                                                        stage.setLocation("unknownPath");
4349                                                        TObjectName location = new TObjectName();
4350                                                        location.setString("unknownPath");
4351                                                        modelFactory.createStageLocation(stage, location);
4352                                                }
4353                                        }
4354
4355                                        if (stage != null && intoTable != null) {
4356                                                if (intoTable != null && !intoTable.getColumns().isEmpty() && !stage.getColumns().isEmpty()) {
4357                                                        for (int i = 0; i < intoTable.getColumns().size(); i++) {
4358                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4359                                                                relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
4360                                                                relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
4361                                                                relation.setProcess(process);
4362                                                        }
4363                                                }
4364                                        }
4365                                } else if (stmt.getStageLocation().getExternalLocation() != null) {
4366                                        Table pathModel = modelFactory.createTableByName(stmt.getStageLocation().getExternalLocation(),
4367                                                        true);
4368                                        pathModel.setPath(true);
4369                                        pathModel.setCreateTable(true);
4370                                        TableColumn fileUriColumn = modelFactory.createFileUri(pathModel,
4371                                                        stmt.getStageLocation().getExternalLocation());
4372                                        if (intoTable != null) {
4373                                                if (intoTable != null && !intoTable.getColumns().isEmpty()) {
4374                                                        for (int i = 0; i < intoTable.getColumns().size(); i++) {
4375                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4376                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4377                                                                relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
4378                                                                relation.setProcess(process);
4379                                                        }
4380                                                }
4381                                        }
4382                                }
4383                        }
4384                        else if (stmt.getSubQuery() != null) {
4385                                analyzeSelectStmt(stmt.getSubQuery());
4386                                
4387                                Table intoTable = modelManager
4388                                                .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
4389                                if (intoTable == null) {
4390                                        intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
4391                                        TObjectName starColumn = new TObjectName();
4392                                        starColumn.setString("*");
4393                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
4394                                        column.setExpandStar(true);
4395                                        column.setPseduo(true);
4396                                        
4397                                        Process process = modelFactory.createProcess(stmt);
4398                                        intoTable.addProcess(process);
4399                                        
4400                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
4401                                        if (resultSetModel != null) {
4402                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
4403                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
4404                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4405                                                        dataflowRelation.setEffectType(EffectType.copy);
4406                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
4407                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(column));
4408                                                }
4409                                        }
4410                                }
4411                        }
4412                }
4413        }
4414
4415        private void analyzeRedshiftCopyStmt(TRedshiftCopy stmt) {
4416                if (stmt.getTableName() != null && stmt.getFromSource() != null) {
4417
4418                        Table intoTable = modelManager
4419                                        .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
4420                        if (intoTable == null) {
4421                                intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
4422                                if (stmt.getColumnList() == null || stmt.getColumnList().size() == 0) {
4423                                        TObjectName starColumn = new TObjectName();
4424                                        starColumn.setString("*");
4425                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
4426                                        if (column != null) {
4427                                                column.setExpandStar(false);
4428                                                column.setPseduo(true);
4429                                        }
4430                                } else {
4431                                        for (TObjectName columnName : stmt.getColumnList()) {
4432                                                modelFactory.createTableColumn(intoTable, columnName, true);
4433                                        }
4434                                }
4435                        }
4436                        Process process = modelFactory.createProcess(stmt);
4437                        intoTable.addProcess(process);
4438
4439                        if (stmt.getFromSource() != null) {
4440                                Table pathModel = modelFactory.createTableByName(stmt.getFromSource(), true);
4441                                pathModel.setPath(true);
4442                                pathModel.setCreateTable(true);
4443                                TObjectName fileUri = new TObjectName();
4444                                fileUri.setString(stmt.getFromSource());
4445                                TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri);
4446                                if (intoTable != null) {
4447                                        if (intoTable != null && !intoTable.getColumns().isEmpty()) {
4448                                                for (int i = 0; i < intoTable.getColumns().size(); i++) {
4449                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4450                                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4451                                                        relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
4452                                                        relation.setProcess(process);
4453                                                }
4454                                        }
4455                                }
4456                        }
4457                }
4458        }
4459
4460        private void analyzeCreateIndexExpressionOperand(TExpression expr, Table tableModel){
4461                if(expr != null){
4462                        TObjectName columnObj = expr.getObjectOperand();
4463                        if(columnObj!=null){
4464                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, columnObj, true);
4465                                tableConstraint.setIndexKey(true);
4466                        }
4467                        else{
4468                                if(expr.getLeftOperand() != null){
4469                                        analyzeCreateIndexExpressionOperand(expr.getLeftOperand(), tableModel);
4470                                }
4471                                if(expr.getRightOperand() != null){
4472                                        analyzeCreateIndexExpressionOperand(expr.getRightOperand(), tableModel);
4473                                }
4474                        }
4475                }
4476
4477        }
4478        private void analyzeCreateIndexStageStmt(TCreateIndexSqlStatement stmt) {
4479                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4480                TOrderByItemList columns = stmt.getColumnNameList();
4481                for(int i=0; i< columns.size(); i++){
4482                        TExpression expr = columns.getOrderByItem(i).getSortKey();
4483                        analyzeCreateIndexExpressionOperand(expr, tableModel);
4484                }
4485        }
4486
4487        private void analyzeCreateSynonymStmt(TCreateSynonymStmt stmt) {
4488                TObjectName sourceTableName = stmt.getForName();
4489                if(sourceTableName == null) {
4490                        return;
4491                }
4492                TCustomSqlStatement createView = viewDDLMap
4493                                .get(DlineageUtil.getTableFullName(sourceTableName.toString()));
4494                if (createView != null) {
4495                        analyzeCustomSqlStmt(createView);
4496                }
4497                Table sourceTableModel = modelFactory.createTableByName(sourceTableName);
4498                Process process = modelFactory.createProcess(stmt);
4499                sourceTableModel.addProcess(process);
4500                if(stmt.getSynonymName()!=null) {
4501                        Table synonymTableModel = modelFactory.createTableByName(stmt.getSynonymName());
4502                        synonymTableModel.setSubType(SubType.synonym);
4503                        if(sourceTableModel.isCreateTable()) {
4504                                synonymTableModel.setCreateTable(true);
4505                                for(TableColumn sourceTableColumn: sourceTableModel.getColumns()) {
4506                                        TObjectName columnName = new TObjectName();
4507                                        columnName.setString(sourceTableColumn.getName());
4508                                        TableColumn synonymTableColumn = new TableColumn(synonymTableModel, columnName);
4509                                        synonymTableModel.addColumn(synonymTableColumn);
4510                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4511                                        relation.setEffectType(EffectType.create_synonym);
4512                                        relation.setTarget(new TableColumnRelationshipElement(synonymTableColumn));
4513                                        relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
4514                                        relation.setProcess(process);
4515                                }
4516                        }
4517                        else {
4518                                TObjectName synonymStarColumn = new TObjectName();
4519                                synonymStarColumn.setString("*");
4520                                TableColumn synonymTableStarColumn = modelFactory.createTableColumn(synonymTableModel,
4521                                                synonymStarColumn, true);
4522                                TObjectName sourceStarColumn = new TObjectName();
4523                                sourceStarColumn.setString("*");
4524                                TableColumn sourceTableStarColumn = modelFactory.createTableColumn(sourceTableModel, sourceStarColumn, true);
4525                                
4526                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4527                                relation.setEffectType(EffectType.create_synonym);
4528                                relation.setTarget(new TableColumnRelationshipElement(synonymTableStarColumn));
4529                                relation.addSource(new TableColumnRelationshipElement(sourceTableStarColumn));
4530                                relation.setProcess(process);
4531                        }
4532                }
4533        }
4534        
4535        private void analyzeRenameStmt(TRenameStmt stmt) {
4536                TObjectName oldTableName = stmt.getOldName();
4537                TObjectName newTableName = stmt.getNewName();
4538                
4539                Table oldNameTableModel = modelFactory.createTableByName(oldTableName);
4540                TObjectName oldStarColumn = new TObjectName();
4541                oldStarColumn.setString("*");
4542                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
4543                
4544                Table newNameTableModel = modelFactory.createTableByName(newTableName);
4545                TObjectName newStarColumn = new TObjectName();
4546                newStarColumn.setString("*");
4547                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true);
4548                
4549                Process process = modelFactory.createProcess(stmt);
4550                newNameTableModel.addProcess(process);
4551                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4552                relation.setEffectType( EffectType.rename_table);
4553                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4554                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4555                relation.setProcess(process);
4556                
4557                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4558                        oldTableStarColumn.setShowStar(false);
4559                        relation.setShowStarRelation(false);
4560                }
4561
4562                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4563                        newTableStarColumn.setShowStar(false);
4564                        relation.setShowStarRelation(false);
4565                }
4566        }
4567        
4568        private void analyzeAlterTableStmt(TAlterTableStatement stmt) {
4569                TTable oldNameTable = stmt.getTargetTable();
4570                if (oldNameTable == null) {
4571                        return;
4572                }
4573
4574                Table oldNameTableModel = modelFactory.createTable(oldNameTable);
4575                TObjectName oldStarColumn = new TObjectName();
4576                oldStarColumn.setString("*");
4577                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
4578
4579                for (int i = 0; stmt.getAlterTableOptionList() != null && i < stmt.getAlterTableOptionList().size(); i++) {
4580                        TAlterTableOption option = stmt.getAlterTableOptionList().getAlterTableOption(i);
4581                        if (option.getOptionType() == EAlterTableOptionType.RenameTable
4582                                        || option.getOptionType() == EAlterTableOptionType.swapWith) {
4583                                TObjectName newTableName = option.getNewTableName();
4584                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4585                                boolean containsTable = false;
4586                                for (int j = 0; j < list.size(); j++) {
4587                                        if (list.get(j) instanceof TTable) {
4588                                                TTable newTableTable = (TTable) list.get(j);
4589                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4590                                                newNameTableModel.setStarStmt("rename_table");
4591
4592                                                TObjectName newStarColumn = new TObjectName();
4593                                                newStarColumn.setString("*");
4594                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4595                                                                newStarColumn, true);
4596
4597                                                Process process = modelFactory.createProcess(stmt);
4598                                                newNameTableModel.addProcess(process);
4599                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4600                                                relation.setEffectType(
4601                                                                option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table
4602                                                                                : EffectType.swap_table);                                               
4603                                                if (option.getOptionType() == EAlterTableOptionType.RenameTable) {
4604                                                        relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4605                                                        relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4606                                                } else if (option.getOptionType() == EAlterTableOptionType.swapWith) {
4607                                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4608                                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4609                                                }
4610                                                relation.setProcess(process);
4611                                                containsTable = true;
4612
4613                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4614                                                        oldTableStarColumn.setShowStar(false);
4615                                                        relation.setShowStarRelation(false);
4616                                                }
4617
4618                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4619                                                        newTableStarColumn.setShowStar(false);
4620                                                        relation.setShowStarRelation(false);
4621                                                }
4622                                        }
4623                                }
4624                                if (!containsTable) {
4625                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4626                                        newNameTableModel.setStarStmt("rename_table");
4627                                        TObjectName newStarColumn = new TObjectName();
4628                                        newStarColumn.setString("*");
4629                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4630                                                        true);
4631
4632                                        Process process = modelFactory.createProcess(stmt);
4633                                        newNameTableModel.addProcess(process);
4634                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4635                                        relation.setEffectType(
4636                                                        option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table
4637                                                                        : EffectType.swap_table);
4638                                        if (option.getOptionType() == EAlterTableOptionType.RenameTable) {
4639                                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4640                                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4641                                        } else if (option.getOptionType() == EAlterTableOptionType.swapWith) {
4642                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4643                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4644                                        }
4645                                        relation.setProcess(process);
4646                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4647                                                oldTableStarColumn.setShowStar(false);
4648                                                relation.setShowStarRelation(false);
4649                                        }
4650
4651                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4652                                                newTableStarColumn.setShowStar(false);
4653                                                relation.setShowStarRelation(false);
4654                                        }
4655
4656                                }
4657                        }
4658                        else if (option.getOptionType() == EAlterTableOptionType.appendFrom) {
4659                                TObjectName newTableName = option.getSourceTableName();
4660                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4661                                boolean containsTable = false;
4662                                for (int j = 0; j < list.size(); j++) {
4663                                        if (list.get(j) instanceof TTable) {
4664                                                TTable newTableTable = (TTable) list.get(j);
4665                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4666                                                newNameTableModel.setStarStmt("append_from");
4667
4668                                                TObjectName newStarColumn = new TObjectName();
4669                                                newStarColumn.setString("*");
4670                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4671                                                                newStarColumn, true);
4672
4673                                                Process process = modelFactory.createProcess(stmt);
4674                                                newNameTableModel.addProcess(process);
4675                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4676                                                relation.setEffectType(EffectType.append_from);
4677                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4678                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4679                                                relation.setProcess(process);
4680                                                containsTable = true;
4681
4682                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4683                                                        oldTableStarColumn.setShowStar(false);
4684                                                        relation.setShowStarRelation(false);
4685                                                }
4686
4687                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4688                                                        newTableStarColumn.setShowStar(false);
4689                                                        relation.setShowStarRelation(false);
4690                                                }
4691                                        }
4692                                }
4693                                if (!containsTable) {
4694                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4695                                        newNameTableModel.setStarStmt("append_from");
4696                                        TObjectName newStarColumn = new TObjectName();
4697                                        newStarColumn.setString("*");
4698                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4699                                                        true);
4700
4701                                        Process process = modelFactory.createProcess(stmt);
4702                                        newNameTableModel.addProcess(process);
4703                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4704                                        relation.setEffectType(EffectType.append_from);
4705                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4706                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4707                                        relation.setProcess(process);
4708                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4709                                                oldTableStarColumn.setShowStar(false);
4710                                                relation.setShowStarRelation(false);
4711                                        }
4712
4713                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4714                                                newTableStarColumn.setShowStar(false);
4715                                                relation.setShowStarRelation(false);
4716                                        }
4717
4718                                }
4719                        }
4720                        else if (option.getOptionType() == EAlterTableOptionType.exchangePartition) {
4721                                TObjectName newTableName = option.getNewTableName();
4722                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4723                                boolean containsTable = false;
4724                                for (int j = 0; j < list.size(); j++) {
4725                                        if (list.get(j) instanceof TTable) {
4726                                                TTable newTableTable = (TTable) list.get(j);
4727                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4728                                                newNameTableModel.setStarStmt("exchange_partition");
4729
4730                                                TObjectName newStarColumn = new TObjectName();
4731                                                newStarColumn.setString("*");
4732                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4733                                                                newStarColumn, true);
4734
4735                                                Process process = modelFactory.createProcess(stmt);
4736                                                newNameTableModel.addProcess(process);
4737                                                {
4738                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4739                                                        relation.setEffectType(EffectType.exchange_partition);
4740                                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4741                                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4742                                                        relation.setProcess(process);
4743                                                        if (option.getPartitionName() != null) {
4744                                                                relation.setPartition(option.getPartitionName().toString());
4745                                                        }
4746                                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4747                                                                oldTableStarColumn.setShowStar(false);
4748                                                                relation.setShowStarRelation(false);
4749                                                        }
4750
4751                                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4752                                                                newTableStarColumn.setShowStar(false);
4753                                                                relation.setShowStarRelation(false);
4754                                                        }
4755                                                }
4756                                                {
4757                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4758                                                        relation.setEffectType(EffectType.exchange_partition);
4759                                                        relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4760                                                        relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
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                                                containsTable = true;   
4776                                        }
4777                                }
4778                                if (!containsTable) {
4779                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4780                                        newNameTableModel.setStarStmt("exchange_partition");
4781                                        TObjectName newStarColumn = new TObjectName();
4782                                        newStarColumn.setString("*");
4783                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4784                                                        true);
4785
4786                                        Process process = modelFactory.createProcess(stmt);
4787                                        newNameTableModel.addProcess(process);
4788                                        {
4789                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4790                                                relation.setEffectType(EffectType.exchange_partition);
4791                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4792                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4793                                                if (option.getPartitionName() != null) {
4794                                                        relation.setPartition(option.getPartitionName().toString());
4795                                                }
4796                                                relation.setProcess(process);
4797                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4798                                                        oldTableStarColumn.setShowStar(false);
4799                                                        relation.setShowStarRelation(false);
4800                                                }
4801
4802                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4803                                                        newTableStarColumn.setShowStar(false);
4804                                                        relation.setShowStarRelation(false);
4805                                                }
4806                                        }
4807                                        {
4808                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4809                                                relation.setEffectType(EffectType.exchange_partition);
4810                                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4811                                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
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                        }
4828                        else if(option.getOptionType() == EAlterTableOptionType.setLocation) {
4829                                TObjectName location = option.getTableLocation();
4830                                Process process = modelFactory.createProcess(stmt);
4831                                process.setType("Set Table Location");
4832                                oldNameTableModel.addProcess(process);
4833                                Table uriFile = modelFactory.createTableByName(location, true);
4834                                uriFile.setPath(true);
4835                                for (int j = 0; j < oldNameTableModel.getColumns().size(); j++) {
4836                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4837                                        TObjectName fileUri = new TObjectName();
4838                                        fileUri.setString("*");
4839                                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
4840                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4841                                        relation.setTarget(new TableColumnRelationshipElement(oldNameTableModel.getColumns().get(j)));
4842                                        relation.setProcess(process);
4843                                }
4844                        }
4845                        else if (option.getOptionType() == EAlterTableOptionType.AddColumn
4846                                        || option.getOptionType() == EAlterTableOptionType.addColumnIfNotExists) {
4847                                if (option.getColumnDefinitionList() != null) {
4848                                        for (TColumnDefinition column : option.getColumnDefinitionList()) {
4849                                                if (column != null && column.getColumnName() != null) {
4850                                                        TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column.getColumnName(), true);
4851                                                        if(this.option.getAnalyzeMode() == AnalyzeMode.crud) {
4852                                                                CrudRelationship crudRelationship = modelFactory.createCrudRelation();
4853                                                                crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
4854                                                                crudRelationship.setEffectType(EffectType.add_table_column);
4855                                                        }
4856                                                }
4857                                        }
4858                                }
4859                        }
4860                        else if (option.getOptionType() == EAlterTableOptionType.DropColumn && this.option.getAnalyzeMode() == AnalyzeMode.crud) {
4861                                if (option.getColumnNameList() != null) {
4862                                        for (TObjectName column : option.getColumnNameList()) {
4863                                                TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column, true);
4864                                                CrudRelationship crudRelationship = modelFactory.createCrudRelation();
4865                                                crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
4866                                                crudRelationship.setEffectType(EffectType.drop_table_column);
4867                                        }
4868                                }
4869                        }
4870                        else if(option.getOptionType() == EAlterTableOptionType.AddConstraint || option.getOptionType() == EAlterTableOptionType.AddConstraintFK
4871                                        || option.getOptionType() == EAlterTableOptionType.AddConstraintPK || option.getOptionType() == EAlterTableOptionType.AddConstraintUnique
4872                                        || option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){
4873                                if (option.getTableConstraint() != null) {
4874                                        TConstraint alertTableConstraint = option.getTableConstraint();
4875                                        TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList();
4876                                        for (int k = 0; k < keyNames.size(); k++) {
4877                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
4878                                                TObjectName referencedTableName = alertTableConstraint.getReferencedObject();
4879                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4880                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
4881                                                if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){
4882                                                        tableConstraint.setPrimaryKey(true);
4883                                                }
4884                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){
4885                                                        tableConstraint.setIndexKey(true);
4886                                                }
4887                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){
4888                                                        tableConstraint.setUnqiueKey(true);
4889                                                }
4890                                                else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
4891                                                        tableConstraint.setForeignKey(true);
4892                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
4893                                                        if (referencedTable == null) {
4894                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
4895                                                        }
4896                                                        TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList();
4897                                                        if (referencedTableColumns != null) {
4898                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
4899                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
4900                                                                                        referencedTableColumns.getObjectName(j), false);
4901                                                                        if (tableColumn != null) {
4902                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4903                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
4904                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4905                                                                                relation.setEffectType(EffectType.foreign_key);
4906                                                                                Process process = modelFactory.createProcess(stmt);
4907                                                                                relation.setProcess(process);
4908                                                                                if(this.option.isShowERDiagram()){
4909                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
4910                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4911                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4912                                                                                }
4913                                                                        }
4914                                                                }
4915                                                        }
4916                                                        else{
4917                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
4918                                                                if (tableColumn != null) {
4919                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4920                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
4921                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4922                                                                        relation.setEffectType(EffectType.foreign_key);
4923                                                                        if(this.option.isShowERDiagram()){
4924                                                                                ERRelationship erRelation = modelFactory.createERRelation();
4925                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4926                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4927                                                                        }
4928                                                                }
4929                                                        }
4930                                                }
4931                                        }
4932                                }
4933                                else if (option.getConstraintList() != null) {
4934                                        for(int iCons=0; iCons<option.getConstraintList().size(); iCons++){
4935                                                TConstraint alertTableConstraint = option.getConstraintList().getConstraint(iCons);
4936                                                TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList();
4937                                                if(keyNames != null){
4938                                                        for (int k = 0; k < keyNames.size(); k++) {
4939                                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
4940                                                                TObjectName referencedTableName = alertTableConstraint.getReferencedObject();
4941                                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4942                                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
4943                                                                if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){
4944                                                                        tableConstraint.setPrimaryKey(true);
4945                                                                }
4946                                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){
4947                                                                        tableConstraint.setIndexKey(true);
4948                                                                }
4949                                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){
4950                                                                        tableConstraint.setUnqiueKey(true);
4951                                                                }
4952                                                                else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
4953                                                                        tableConstraint.setForeignKey(true);
4954                                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
4955                                                                        if (referencedTable == null) {
4956                                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
4957                                                                        }
4958                                                                        TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList();
4959                                                                        if (referencedTableColumns != null) {
4960                                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
4961                                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
4962                                                                                                        referencedTableColumns.getObjectName(j), false);
4963                                                                                        if (tableColumn != null) {
4964                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4965                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
4966                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4967                                                                                                relation.setEffectType(EffectType.foreign_key);
4968                                                                                                Process process = modelFactory.createProcess(stmt);
4969                                                                                                relation.setProcess(process);
4970                                                                                                if(this.option.isShowERDiagram()){
4971                                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
4972                                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4973                                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4974                                                                                                }
4975                                                                                        }
4976                                                                                }
4977                                                                        }
4978                                                                        else{
4979                                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
4980                                                                                if (tableColumn != null) {
4981                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4982                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
4983                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4984                                                                                        relation.setEffectType(EffectType.foreign_key);
4985                                                                                        Process process = modelFactory.createProcess(stmt);
4986                                                                                        relation.setProcess(process);
4987                                                                                        if(this.option.isShowERDiagram()){
4988                                                                                                ERRelationship erRelation = modelFactory.createERRelation();
4989                                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4990                                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4991                                                                                        }
4992                                                                                }
4993                                                                        }
4994                                                                }
4995                                                        }
4996                                                }
4997                                        }
4998                                }
4999                                else if (option.getIndexCols() != null){
5000                                        TPTNodeList<TColumnWithSortOrder> keyNames = option.getIndexCols();
5001                                        for (int k = 0; k < keyNames.size(); k++) {
5002                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
5003                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
5004                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
5005                                                if(option.getOptionType() == EAlterTableOptionType.AddConstraintPK){
5006                                                        tableConstraint.setPrimaryKey(true);
5007                                                }
5008                                                else if(option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){
5009                                                        tableConstraint.setIndexKey(true);
5010                                                }
5011                                                else if(option.getOptionType() == EAlterTableOptionType.AddConstraintUnique){
5012                                                        tableConstraint.setUnqiueKey(true);
5013                                                }
5014                                                else if (option.getOptionType() == EAlterTableOptionType.AddConstraintFK) {
5015                                                        TObjectName referencedTableName = option.getReferencedObjectName();
5016                                                        tableConstraint.setForeignKey(true);
5017                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
5018                                                        if (referencedTable == null) {
5019                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
5020                                                        }
5021                                                        TObjectNameList referencedTableColumns = option.getReferencedColumnList();
5022                                                        if (referencedTableColumns != null) {
5023                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
5024                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
5025                                                                                        referencedTableColumns.getObjectName(j), false);
5026                                                                        if (tableColumn != null) {
5027                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
5028                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
5029                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5030                                                                                relation.setEffectType(EffectType.foreign_key);
5031                                                                                Process process = modelFactory.createProcess(stmt);
5032                                                                                relation.setProcess(process);
5033                                                                                if(this.option.isShowERDiagram()){
5034                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
5035                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
5036                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5037                                                                                }
5038                                                                        }
5039                                                                }
5040                                                        }
5041                                                        else{
5042                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
5043                                                                if (tableColumn != null) {
5044                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
5045                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
5046                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5047                                                                        relation.setEffectType(EffectType.foreign_key);
5048                                                                        Process process = modelFactory.createProcess(stmt);
5049                                                                        relation.setProcess(process);
5050                                                                        if(this.option.isShowERDiagram()){
5051                                                                                ERRelationship erRelation = modelFactory.createERRelation();
5052                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
5053                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5054                                                                        }
5055                                                                }
5056                                                        }
5057                                                }
5058                                        }
5059                                }
5060                        }
5061                }
5062        }
5063
5064        private void analyzeDeleteStmt(TDeleteSqlStatement stmt) {
5065                TTable table = stmt.getTargetTable();
5066                if (table == null)
5067                        return;
5068                
5069                if (table.getCTE() != null) {
5070                        table = table.getCTE().getSubquery().getTables().getTable(0);
5071                } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) {
5072                        table = table.getLinkTable().getSubquery().getTables().getTable(0);
5073                } else if (table.getSubquery() != null) {
5074                        table = table.getSubquery().getTables().getTable(0);
5075                }
5076                
5077                Table tableModel = modelFactory.createTable(table);
5078                if (table.getLinkedColumns() != null && table.getLinkedColumns().size() > 0) {
5079                        for (int j = 0; j < table.getLinkedColumns().size(); j++) {
5080                                TObjectName object = table.getLinkedColumns().getObjectName(j);
5081
5082                                if (object.getDbObjectType() == EDbObjectType.variable) {
5083                                        continue;
5084                                }
5085
5086                                if (object.getColumnNameOnly().startsWith("@")
5087                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
5088                                        continue;
5089                                }
5090
5091                                if (object.getColumnNameOnly().startsWith(":")
5092                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
5093                                        continue;
5094                                }
5095
5096                                if (!isBuiltInFunctionName(object)) {
5097                                        if (object.getSourceTable() == null || object.getSourceTable() == table) {
5098                                                modelFactory.createTableColumn(tableModel, object, false);
5099                                        }
5100                                }
5101                        }
5102                }
5103
5104                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
5105                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
5106                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
5107                        crudRelationship.setEffectType(EffectType.delete);
5108                }
5109                
5110                if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) {
5111                        analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where,
5112                                        EffectType.delete);
5113                }
5114        }
5115
5116        private TObjectName getProcedureName(TStoredProcedureSqlStatement stmt) {
5117                if (stmt instanceof TTeradataCreateProcedure) {
5118                        return ((TTeradataCreateProcedure) stmt).getProcedureName();
5119                }
5120                return stmt.getStoredProcedureName();
5121        }
5122
5123        private void analyzePlsqlCreatePackage(TPlsqlCreatePackage stmt) {
5124                TObjectName procedureName = getProcedureName(stmt);
5125                OraclePackage oraclePackage;
5126                if (procedureName != null) {
5127                        if (this.modelManager.getOraclePackageByName(
5128                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))) == null) {
5129                                oraclePackage = this.modelFactory.createOraclePackage(stmt);
5130
5131                                if (stmt.getParameterDeclarations() != null) {
5132                                        TParameterDeclarationList parameters = stmt.getParameterDeclarations();
5133
5134                                        for (int i = 0; i < parameters.size(); ++i) {
5135                                                TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i);
5136                                                if (parameter.getParameterName() != null) {
5137                                                        this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1);
5138                                                } else if (parameter.getDataType() != null) {
5139                                                        this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1);
5140                                                }
5141                                        }
5142                                }
5143
5144                                ModelBindingManager.setGlobalOraclePackage(oraclePackage);
5145                        } else {
5146                                ModelBindingManager.setGlobalOraclePackage(this.modelManager.getOraclePackageByName(
5147                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))));
5148                        }
5149                        
5150                        try {
5151                                if (stmt.getDeclareStatements() != null) {
5152                                        for (int i = 0; i < stmt.getDeclareStatements().size(); ++i) {
5153                                                analyzeCustomSqlStmt(stmt.getDeclareStatements().get(i));
5154                                        }
5155                                }
5156                        } finally {
5157                                ModelBindingManager.removeGlobalOraclePackage();
5158                        }
5159                }
5160        }
5161
5162        private void analyzeStoredProcedureStmt(TStoredProcedureSqlStatement stmt) {
5163
5164                if (stmt instanceof TPlsqlCreatePackage) {
5165                        analyzePlsqlCreatePackage((TPlsqlCreatePackage) stmt);
5166                        return;
5167                }
5168                
5169                ModelBindingManager.setGlobalProcedure(stmt);
5170
5171                try {
5172                        Procedure procedure = null;
5173        
5174                        TObjectName procedureName = getProcedureName(stmt);
5175                        if (procedureName != null) {
5176                                procedure = this.modelFactory.createProcedure(stmt);
5177                                if (procedure != null) {
5178                                        modelManager.bindModel(stmt, procedure);
5179                                }
5180                                if (ModelBindingManager.getGlobalOraclePackage() != null) {
5181                                        ModelBindingManager.getGlobalOraclePackage().addProcedure(procedure);
5182                                        procedure.setParentPackage(ModelBindingManager.getGlobalOraclePackage());
5183                                }
5184                                if (stmt.getParameterDeclarations() != null) {
5185                                        TParameterDeclarationList parameters = stmt.getParameterDeclarations();
5186        
5187                                        for (int i = 0; i < parameters.size(); ++i) {
5188                                                TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i);
5189                                                Argument argument = null;
5190                                                TObjectName argumentName = null;
5191                                                if (parameter.getParameterName() != null) {
5192                                                        argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1);
5193                                                        argumentName = parameter.getParameterName();
5194                                                } else if (parameter.getDataType() != null) {
5195                                                        argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1);
5196                                                }
5197                                                
5198                                                if (argument != null) {
5199                                                        if (argumentName == null) {
5200                                                                argumentName = new TObjectName();
5201                                                                argumentName.setString(argument.getName());
5202                                                        }
5203                                                        Variable variable = modelFactory.createVariable(argument.getName());
5204                                                        if (argument.getMode() == EParameterMode.in || argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
5205                                                                variable.setSubType(SubType.of(argument.getMode().name()));
5206                                                        } else {
5207                                                                variable.setSubType(SubType.argument);
5208                                                        }
5209                                                        if(isSimpleDataType(argument.getDataType())){
5210                                                                modelFactory.createTableColumn(variable, argumentName, true);
5211                                                        }
5212                                                        else {
5213                                                                TObjectName variableProperties = new TObjectName();
5214                                                                variableProperties.setString("*");
5215                                                                modelFactory.createTableColumn(variable, variableProperties, true);
5216                                                        }
5217                                                }
5218                                        }
5219                                }
5220                        }
5221        
5222                        if (stmt instanceof TCreateTriggerStmt) {
5223                                TCreateTriggerStmt trigger = (TCreateTriggerStmt) stmt;
5224        
5225                                if (trigger.getFunctionCall() != null) {
5226                                        modelFactory.createProcedureFromFunctionCall(trigger.getFunctionCall());
5227                                }
5228        
5229                                if (trigger.getTables() != null) {
5230                                        for (int i = 0; i < trigger.getTables().size(); i++) {
5231                                                Table tableModel = this.modelFactory.createTriggerOnTable(trigger.getTables().getTable(i));
5232                                        }
5233                                }
5234                        }
5235        
5236                        if (stmt instanceof TPlsqlCreateTrigger
5237                                        && ((TPlsqlCreateTrigger) stmt).getTriggeringClause().getEventClause() instanceof TDmlEventClause) {
5238                                TPlsqlCreateTrigger trigger = (TPlsqlCreateTrigger) stmt;
5239                                TDmlEventClause clause = (TDmlEventClause) ((TPlsqlCreateTrigger) stmt).getTriggeringClause()
5240                                                .getEventClause();
5241                                Table sourceTable = modelFactory.createTableByName(clause.getTableName());
5242        
5243                                for (TTriggerEventItem item : clause.getEventItems()) {
5244                                        if (item instanceof TDmlEventItem) {
5245                                                if (((TDmlEventItem) item).getColumnList() != null) {
5246                                                        for (TObjectName column : ((TDmlEventItem) item).getColumnList()) {
5247                                                                modelFactory.createTableColumn(sourceTable, column, true);
5248                                                        }
5249                                                }
5250                                        }
5251                                }
5252        
5253                                for (TCustomSqlStatement subStmt : ((TPlsqlCreateTrigger) stmt).getStatements()) {
5254                                        if (!(subStmt instanceof TCommonBlock))
5255                                                continue;
5256                                        for (TCustomSqlStatement blockSubStmt : ((TCommonBlock) subStmt).getStatements()) {
5257                                                if (!(blockSubStmt instanceof TBasicStmt))
5258                                                        continue;
5259                                                TBasicStmt basicStmt = (TBasicStmt) blockSubStmt;
5260                                                TExpression expression = basicStmt.getExpr();
5261                                                if (expression != null && expression.getExpressionType() == EExpressionType.function_t) {
5262                                                        Procedure targetProcedure = modelManager.getProcedureByName(DlineageUtil
5263                                                                        .getTableFullName(expression.getFunctionCall().getFunctionName().toString()));
5264                                                        if (targetProcedure == null) {
5265                                                                targetProcedure = modelManager
5266                                                                                .getProcedureByName(DlineageUtil.getTableFullName(procedure.getSchema() + "."
5267                                                                                                + expression.getFunctionCall().getFunctionName().toString()));
5268                                                        }
5269                                                        if (targetProcedure != null && expression.getFunctionCall().getArgs() != null && expression
5270                                                                        .getFunctionCall().getArgs().size() == targetProcedure.getArguments().size()) {
5271                                                                for (int j = 0; j < expression.getFunctionCall().getArgs().size(); j++) {
5272                                                                        TExpression columnExpr = expression.getFunctionCall().getArgs().getExpression(j);
5273                                                                        if (columnExpr.getExpressionType() == EExpressionType.simple_object_name_t) {
5274                                                                                TObjectName columnObject = columnExpr.getObjectOperand();
5275                                                                                if (columnObject.toString().indexOf(":") != -1) {
5276                                                                                        TableColumn tableColumn = modelFactory.createTableColumn(sourceTable,
5277                                                                                                        columnObject, true);
5278                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
5279                                                                                        relation.setEffectType(EffectType.trigger);
5280                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
5281                                                                                        relation.setTarget(
5282                                                                                                        new ArgumentRelationshipElement(targetProcedure.getArguments().get(j)));
5283                                                                                        Process process = modelFactory.createProcess(stmt);
5284                                                                                        relation.setProcess(process);
5285                                                                                }
5286                                                                        }
5287                                                                }
5288                                                        }
5289                                                }
5290                                        }
5291                                }
5292                        }
5293        
5294                        if (stmt instanceof TMssqlCreateFunction) {
5295                                TMssqlCreateFunction createFunction = (TMssqlCreateFunction) stmt;
5296                                if (createFunction.getReturnTableVaraible() != null && createFunction.getReturnTableDefinitions() != null) {
5297                                        Table tableModel = this.modelFactory.createTableByName(createFunction.getReturnTableVaraible(), true);
5298                                        tableModel.setCreateTable(true);
5299                                        String procedureParent = createFunction.getFunctionName().toString();
5300                                        if (procedureParent != null) {
5301                                                tableModel.setParent(procedureParent);
5302                                        }
5303                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
5304        
5305                                        if (createFunction.getReturnTableDefinitions() != null) {
5306                                                for (int j = 0; j < createFunction.getReturnTableDefinitions().size(); j++) {
5307                                                        TTableElement tableElement = createFunction.getReturnTableDefinitions().getTableElement(j);
5308                                                        TColumnDefinition column = tableElement.getColumnDefinition();
5309                                                        if (column != null && column.getColumnName() != null) {
5310                                                                modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
5311                                                        }
5312                                                }
5313                                        }
5314                                }
5315        
5316                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) {
5317                                        String procedureParent = createFunction.getFunctionName().toString();
5318                                        analyzeSelectStmt(createFunction.getReturnStmt().getSubquery());
5319                                        ResultSet resultSetModel = (ResultSet) modelManager
5320                                                        .getModel(createFunction.getReturnStmt().getSubquery());
5321                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5322                                                        resultSetModel);
5323                                }
5324                        } else if (stmt instanceof TCreateFunctionStmt) {
5325                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt;
5326                                if (createFunction.getReturnDataType() != null
5327                                                && createFunction.getReturnDataType().getColumnDefList() != null) {
5328                                        Table tableModel = this.modelFactory.createTableByName(createFunction.getFunctionName(), true);
5329                                        tableModel.setCreateTable(true);
5330                                        String procedureParent = createFunction.getFunctionName().toString();
5331                                        if (procedureParent != null) {
5332                                                tableModel.setParent(procedureParent);
5333                                        }
5334        
5335                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
5336                                        for (int j = 0; j < createFunction.getReturnDataType().getColumnDefList().size(); j++) {
5337                                                TColumnDefinition column = createFunction.getReturnDataType().getColumnDefList().getColumn(j);
5338                                                if (column != null && column.getColumnName() != null) {
5339                                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
5340                                                }
5341                                        }
5342        
5343                                        if (createFunction.getSqlQuery() != null) {
5344                                                analyzeSelectStmt(createFunction.getSqlQuery());
5345                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(createFunction.getSqlQuery());
5346                                                if (resultSetModel != null) {
5347                                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
5348                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
5349                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
5350                                                                        TableColumn tableColumn = tableModel.getColumns().get(j);
5351                                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(resultColumn.getName()),
5352                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
5353                                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5354                                                                                dataflowRelation.setEffectType(EffectType.select);
5355                                                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
5356                                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
5357                                                                        }
5358                                                                }
5359                                                        }
5360                                                }
5361                                        }
5362                                }
5363                                
5364                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) {
5365                                        String procedureParent = createFunction.getFunctionName().toString();
5366                                        analyzeSelectStmt(createFunction.getReturnStmt().getSubquery());
5367                                        ResultSet resultSetModel = (ResultSet) modelManager
5368                                                        .getModel(createFunction.getReturnStmt().getSubquery());
5369                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5370                                                        resultSetModel);
5371                                }
5372                                
5373                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getReturnExpr() != null) {
5374                                        TExpression returnExpression =  createFunction.getReturnStmt().getReturnExpr();
5375                                        ResultSet returnResult = modelFactory.createResultSet(createFunction.getReturnStmt(), false);
5376                                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5377                                        
5378                                        TExpression expression = createFunction.getReturnStmt().getReturnExpr();
5379                                        analyzeResultColumnExpressionRelation(resultColumn, expression);
5380        
5381                                        String procedureParent = createFunction.getFunctionName().toString();
5382                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5383                                                        returnResult);
5384                                }
5385                        }
5386        
5387                        if (stmt instanceof TCreateProcedureStmt) {
5388                                TCreateProcedureStmt createProcedure = (TCreateProcedureStmt) stmt;
5389                                if (EDbVendor.dbvsnowflake == option.getVendor() && createProcedure.getRoutineBodyInConstant() != null) {
5390                                        extractSnowflakeSQLFromProcedure(createProcedure);
5391                                }
5392                        }
5393                                
5394                        if (stmt.getStatements().size() > 0) {
5395                                for (int i = 0; i < stmt.getStatements().size(); ++i) {
5396                                        this.analyzeCustomSqlStmt(stmt.getStatements().get(i));
5397                                }
5398                        }
5399
5400                        if (stmt.getBodyStatements().size() > 0) {
5401                                for (int i = 0; i < stmt.getBodyStatements().size(); ++i) {
5402                                        this.analyzeCustomSqlStmt(stmt.getBodyStatements().get(i));
5403                                }
5404                        }
5405                        
5406                        if (procedure != null && !getLastSelectStmt(stmt).isEmpty()) {
5407                                for (TSelectSqlStatement select : getLastSelectStmt(stmt)) {
5408                                        ResultSet resultSet = (ResultSet) modelManager.getModel(select);
5409                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedure.getName()),
5410                                                        resultSet);
5411                                }
5412//                              List<Argument> outArgs = new ArrayList<Argument>();
5413//                              for (int i = 0; i < procedure.getArguments().size(); i++) {
5414//                                      Argument argument = procedure.getArguments().get(i);
5415//                                      if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
5416//                                              outArgs.add(argument);
5417//                                      }
5418//                              }
5419//
5420//                              if (resultSet != null && resultSet.getColumns().size() == outArgs.size()) {
5421//                                      for (int i = 0; i < outArgs.size(); i++) {
5422//                                              Argument argument = outArgs.get(i);
5423//                                              Variable variable = modelFactory.createVariable(argument.getName(), false);
5424//                                              if (variable != null) {
5425//                                                      DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5426//                                                      dataflowRelation.setEffectType(EffectType.output);
5427//                                                      dataflowRelation
5428//                                                                      .addSource(new ResultColumnRelationshipElement(resultSet.getColumns().get(i)));
5429//                                                      dataflowRelation
5430//                                                                      .setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0)));
5431//                                              }
5432//                                      }
5433//
5434//                              }
5435                        }
5436
5437                        if (stmt instanceof TCreateFunctionStmt && ((TCreateFunctionStmt)stmt).getSqlExpression()!=null) {
5438                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt;
5439                                TExpression returnExpression = createFunction.getSqlExpression();
5440
5441                                ResultSet returnResult = modelFactory.createResultSet(stmt, false);
5442                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5443
5444                                columnsInExpr visitor = new columnsInExpr();
5445                                returnExpression.inOrderTraverse(visitor);
5446
5447                                List<TObjectName> objectNames = visitor.getObjectNames();
5448                                List<TParseTreeNode> functions = visitor.getFunctions();
5449                                List<TParseTreeNode> constants = visitor.getConstants();
5450                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5451
5452                                if (functions != null && !functions.isEmpty()) {
5453                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5454                                }
5455                                if (subquerys != null && !subquerys.isEmpty()) {
5456                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5457                                }
5458                                if (objectNames != null && !objectNames.isEmpty()) {
5459                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5460                                }
5461                                if (constants != null && !constants.isEmpty()) {
5462                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5463                                }
5464
5465                                String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5466                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5467                                                returnResult);
5468                        }
5469                } finally {
5470                        ModelBindingManager.removeGlobalProcedure();
5471                }
5472
5473        }
5474
5475        private boolean isSimpleDataType(TTypeName dataType) {
5476                if (dataType.getDataType() == EDataType.variant_t) {
5477                        return false;
5478                }
5479                if (dataType.getDataType() == EDataType.cursor_t) {
5480                        return false;
5481                }
5482                if (dataType.getDataType() == EDataType.generic_t) {
5483                        return false;
5484                }
5485                if (dataType.getDataType() == EDataType.unknown_t) {
5486                        return false;
5487                }
5488                if (dataType.getDataType() == EDataType.sql_variant_t) {
5489                        return false;
5490                }
5491                if (dataType.getDataType() == EDataType.table_t) {
5492                        return false;
5493                }
5494                if (dataType.getDataType() == EDataType.raw_t) {
5495                        return false;
5496                }
5497                if (dataType.getDataType() == EDataType.resultset_t) {
5498                        return false;
5499                }
5500                if (dataType.getDataType() == EDataType.row_t) {
5501                        return false;
5502                }
5503                if (dataType.getDataType() == EDataType.map_t) {
5504                        return false;
5505                }
5506                if (dataType.getDataType() == EDataType.anyType_t) {
5507                        return false;
5508                }
5509                if (dataType.getDataType() == EDataType.struct_t) {
5510                        return false;
5511                }
5512                if (dataType.getDataType() == EDataType.structType_t) {
5513                        return false;
5514                }
5515                if (dataType.getDataType() == EDataType.mapType_t) {
5516                        return false;
5517                }
5518                return true;
5519        }
5520
5521        protected void analyzeResultColumnExpressionRelation(Object resultColumn, TExpression expression) {
5522                columnsInExpr visitor = new columnsInExpr();
5523                expression.inOrderTraverse(visitor);
5524                List<TObjectName> objectNames = visitor.getObjectNames();
5525                List<TParseTreeNode> functions = visitor.getFunctions();
5526                List<TParseTreeNode> constants = visitor.getConstants();
5527                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5528
5529                if (functions != null && !functions.isEmpty()) {
5530                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5531                }
5532                if (subquerys != null && !subquerys.isEmpty()) {
5533                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5534                }
5535                if (objectNames != null && !objectNames.isEmpty()) {
5536                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5537                }
5538                if (constants != null && !constants.isEmpty()) {
5539                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5540                }
5541        }
5542
5543        private void analyzeDb2ReturnStmt(TDb2ReturnStmt stmt) {
5544                if (stmt.getReturnExpr() != null) {
5545                        TExpression returnExpression = stmt.getReturnExpr();
5546                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5547                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5548                        
5549                        columnsInExpr visitor = new columnsInExpr();
5550                        stmt.getReturnExpr().inOrderTraverse(visitor);
5551                        
5552                        List<TObjectName> objectNames = visitor.getObjectNames();
5553                        List<TParseTreeNode> functions = visitor.getFunctions();
5554                        List<TParseTreeNode> constants = visitor.getConstants();
5555                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5556
5557                        if (functions != null && !functions.isEmpty()) {
5558                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5559                        }
5560                        if (subquerys != null && !subquerys.isEmpty()) {
5561                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5562                        }
5563                        if (objectNames != null && !objectNames.isEmpty()) {
5564                                analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5565                        }
5566                        if (constants != null && !constants.isEmpty()) {
5567                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5568                        }
5569
5570                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5571                        if (procedureParent != null) {
5572                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5573                                                returnResult);
5574                        }
5575                }
5576        }
5577
5578        private void analyzeReturnStmt(TReturnStmt stmt) {
5579                if (stmt.getResultColumnList() != null) {
5580                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5581                        for (TResultColumn column : stmt.getResultColumnList()) {
5582                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column);
5583
5584                                columnsInExpr visitor = new columnsInExpr();
5585                                column.getExpr().inOrderTraverse(visitor);
5586
5587                                List<TObjectName> objectNames = visitor.getObjectNames();
5588                                List<TParseTreeNode> functions = visitor.getFunctions();
5589                                List<TParseTreeNode> constants = visitor.getConstants();
5590                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5591
5592                                if (functions != null && !functions.isEmpty()) {
5593                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5594                                }
5595                                if (subquerys != null && !subquerys.isEmpty()) {
5596                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5597                                }
5598                                if (objectNames != null && !objectNames.isEmpty()) {
5599                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5600                                }
5601                                if (constants != null && !constants.isEmpty()) {
5602                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5603                                }
5604
5605                        }
5606
5607                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5608                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5609                                        returnResult);
5610                }
5611                else if(stmt.getExpression()!=null){
5612                        TExpression returnExpression = stmt.getExpression();
5613                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5614                        
5615                        columnsInExpr visitor = null;
5616                        List<TSelectSqlStatement> subquerys = null;
5617                        
5618                        if (returnExpression.getFunctionCall() != null
5619                                        && returnExpression.getFunctionCall().getFunctionName().toString().equalsIgnoreCase("table")
5620                                        && returnExpression.getFunctionCall().getArgs() != null
5621                                        && returnExpression.getFunctionCall().getArgs().size()>0) {
5622                                visitor = new columnsInExpr();
5623                                returnExpression.getFunctionCall().getArgs().getExpression(0).inOrderTraverse(visitor);
5624                                subquerys = visitor.getSubquerys();
5625                                if (subquerys != null && !subquerys.isEmpty()) {
5626                                        analyzeSelectStmt(subquerys.get(0));
5627                                        ResultSet resultSet = (ResultSet) modelManager.getModel(subquerys.get(0));
5628                                        if (resultSet != null && resultSet.getColumns() != null) {
5629                                                for (ResultColumn column : resultSet.getColumns()) {
5630                                                        TObjectName columnName = new TObjectName();
5631                                                        columnName.setString(column.getName());
5632                                                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, columnName);
5633                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5634                                                        dataflowRelation.setEffectType(EffectType.select);
5635                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(column));
5636                                                        dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5637                                                }
5638                                        }
5639                                        returnResult.setDetermined(resultSet.isDetermined());
5640                                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5641                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5642                                                        returnResult);
5643                                        return;
5644                                }
5645                        }
5646                        
5647                        ResultColumn resultColumn = null;
5648                        if (returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5649                                TObjectName columnName = new TObjectName();
5650                                columnName.setString("*");
5651                                resultColumn = modelFactory.createResultColumn(returnResult, columnName);
5652                        }
5653                        else {
5654                                resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5655                        }
5656
5657                        visitor = new columnsInExpr();
5658                        stmt.getExpression().inOrderTraverse(visitor);
5659
5660                        List<TObjectName> objectNames = visitor.getObjectNames();
5661                        List<TParseTreeNode> functions = visitor.getFunctions();
5662                        List<TParseTreeNode> constants = visitor.getConstants();
5663                        subquerys = visitor.getSubquerys();
5664
5665                        if (functions != null && !functions.isEmpty()) {
5666                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5667                        }
5668                        if (subquerys != null && !subquerys.isEmpty()) {
5669                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5670                        }
5671                        if (objectNames != null && !objectNames.isEmpty()) {
5672                                DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5673                                //如果variable对应的不是一个复杂结构,则resultColumn不要设置为*
5674                                if (relation != null && relation.getTarget().getElement() == resultColumn && relation.getSources().size() == 1) {
5675                                        Object column = relation.getSources().iterator().next().getElement();
5676                                        boolean star = true;
5677                                        if (column instanceof TableColumn && ((TableColumn) column).getName().indexOf("*") == -1) {
5678                                                star = false;
5679                                        }
5680                                        if (column instanceof ResultColumn && ((ResultColumn) column).getName().indexOf("*") == -1) {
5681                                                star = false;
5682                                        }
5683                                        if (!star && returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5684                                                resultColumn = modelFactory.createResultColumn(returnResult, returnExpression.getObjectOperand());
5685                                                returnResult.getColumns().clear();
5686                                                returnResult.addColumn(resultColumn);
5687                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5688                                        }
5689                                }
5690                        }
5691                        if (constants != null && !constants.isEmpty()) {
5692                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5693                        }
5694
5695                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5696                        if (procedureParent != null) {
5697                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5698                                                returnResult);
5699                        }
5700                }
5701        }
5702
5703        private void analyzeMssqlReturnStmt(TMssqlReturn stmt) {
5704                if (stmt.getResultColumnList() != null) {
5705                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5706                        for (TResultColumn column : stmt.getResultColumnList()) {
5707                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column);
5708
5709                                columnsInExpr visitor = new columnsInExpr();
5710                                column.getExpr().inOrderTraverse(visitor);
5711
5712                                List<TObjectName> objectNames = visitor.getObjectNames();
5713                                List<TParseTreeNode> functions = visitor.getFunctions();
5714                                List<TParseTreeNode> constants = visitor.getConstants();
5715                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5716
5717                                if (functions != null && !functions.isEmpty()) {
5718                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5719                                }
5720                                if (subquerys != null && !subquerys.isEmpty()) {
5721                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5722                                }
5723                                if (objectNames != null && !objectNames.isEmpty()) {
5724                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5725                                }
5726                                if (constants != null && !constants.isEmpty()) {
5727                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5728                                }
5729
5730                        }
5731
5732                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5733                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5734                                        returnResult);
5735                }
5736                else if(stmt.getReturnExpr()!=null){
5737                        TExpression returnExpression = stmt.getReturnExpr();
5738                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5739                        
5740                        if (returnExpression.getSubQuery() == null) {
5741                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5742                                columnsInExpr visitor = new columnsInExpr();
5743                                stmt.getReturnExpr().inOrderTraverse(visitor);
5744
5745                                List<TObjectName> objectNames = visitor.getObjectNames();
5746                                List<TParseTreeNode> functions = visitor.getFunctions();
5747                                List<TParseTreeNode> constants = visitor.getConstants();
5748                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5749
5750                                if (functions != null && !functions.isEmpty()) {
5751                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5752                                }
5753                                if (subquerys != null && !subquerys.isEmpty()) {
5754                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5755                                }
5756                                if (objectNames != null && !objectNames.isEmpty()) {
5757                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5758                                }
5759                                if (constants != null && !constants.isEmpty()) {
5760                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5761                                }
5762                        }
5763                        else {
5764                                analyzeSelectStmt(returnExpression.getSubQuery());
5765                                ResultSet subResultSet = (ResultSet)modelManager.getModel(returnExpression.getSubQuery());
5766                                if (subResultSet != null) {
5767                                        for (ResultColumn subResultColumn : subResultSet.getColumns()) {
5768                                                TObjectName objectName = new TObjectName();
5769                                                objectName.setString(subResultColumn.getName());
5770                                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, objectName);
5771                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5772                                                dataflowRelation.setEffectType(EffectType.select);
5773                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(subResultColumn));
5774                                                dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5775
5776                                        }
5777                                        
5778                                        if(subResultSet.getRelationRows().hasRelation()) {
5779                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
5780                                                impactRelation.setEffectType(EffectType.select);
5781                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
5782                                                                subResultSet.getRelationRows()));
5783                                                impactRelation.setTarget(
5784                                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(returnResult.getRelationRows()));
5785                                        }
5786                                }
5787                        }
5788                        
5789                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5790                        if (procedureParent != null) {
5791                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5792                                                returnResult);
5793                        }
5794                }
5795        }
5796        
5797        private void analyzeFetchStmt(TFetchStmt stmt) {
5798                if (stmt.getVariableNames() != null) {
5799                        for (int i = 0; i < stmt.getVariableNames().size(); i++) {
5800                                TExpression variableExpression = stmt.getVariableNames().getExpression(i);
5801                                if (variableExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5802                                        TObjectName columnObject = variableExpression.getObjectOperand();
5803                                        if (columnObject.getDbObjectType() == EDbObjectType.variable) {
5804                                                continue;
5805                                        }
5806
5807                                        if (columnObject.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql
5808                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
5809                                                continue;
5810                                        }
5811
5812                                        if (columnObject.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana
5813                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
5814                                                continue;
5815                                        }
5816
5817                                        Variable cursorVariable = modelFactory.createVariable(columnObject);
5818                                        cursorVariable.setSubType(SubType.record);
5819                                        if (cursorVariable.isDetermined()) {
5820                                                if (stmt.getCursorName() != null) {
5821                                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5822                                                        String variableString = stmt.getCursorName().toString();
5823                                                        if (variableString.startsWith(":")) {
5824                                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5825                                                        }
5826                                                        if (!SQLUtil.isEmpty(procedureName)) {
5827                                                                variableString = procedureName + "."
5828                                                                                + SQLUtil.getIdentifierNormalTableName(variableString);
5829                                                        }
5830                                                        Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
5831                                                        if (cursor != null) {
5832                                                                for (TableColumn variableProperty : cursorVariable.getColumns()) {
5833                                                                        boolean flag = false;
5834                                                                        for (TableColumn cursorColumn : cursor.getColumns()) {
5835                                                                                if (getColumnName(cursorColumn.getName())
5836                                                                                                .equalsIgnoreCase(variableProperty.getName())) {
5837                                                                                        DataFlowRelationship dataflowRelation = modelFactory
5838                                                                                                        .createDataFlowRelation();
5839                                                                                        dataflowRelation.setEffectType(EffectType.cursor);
5840                                                                                        dataflowRelation
5841                                                                                                        .addSource(new TableColumnRelationshipElement(cursorColumn));
5842                                                                                        dataflowRelation
5843                                                                                                        .setTarget(new TableColumnRelationshipElement(variableProperty));
5844                                                                                        flag = true;
5845                                                                                        break;
5846                                                                                }
5847                                                                        }
5848
5849                                                                        if (!flag) {
5850                                                                                if (cursor.getColumns().size() == stmt.getVariableNames().size()) {
5851                                                                                        DataFlowRelationship dataflowRelation = modelFactory
5852                                                                                                        .createDataFlowRelation();
5853                                                                                        dataflowRelation.setEffectType(EffectType.cursor);
5854                                                                                        dataflowRelation
5855                                                                                                        .setTarget(new TableColumnRelationshipElement(variableProperty));
5856                                                                                        dataflowRelation.addSource(
5857                                                                                                        new TableColumnRelationshipElement(cursor.getColumns().get(i)));
5858                                                                                }
5859                                                                                else {
5860                                                                                        for (int j = 0; j < cursor.getColumns().size(); j++) {
5861                                                                                                DataFlowRelationship dataflowRelation = modelFactory
5862                                                                                                                .createDataFlowRelation();
5863                                                                                                dataflowRelation.setEffectType(EffectType.cursor);
5864                                                                                                if (stmt.getVariableNames().size() == 1) {
5865                                                                                                        dataflowRelation.addSource(new TableColumnRelationshipElement(
5866                                                                                                                        cursor.getColumns().get(j)));
5867                                                                                                } else {
5868                                                                                                        dataflowRelation.addSource(new TableColumnRelationshipElement(
5869                                                                                                                        cursor.getColumns().get(j), i));
5870                                                                                                }
5871                                                                                                dataflowRelation.setTarget(
5872                                                                                                                new TableColumnRelationshipElement(variableProperty));
5873                                                                                        }
5874                                                                                }
5875                                                                        }
5876                                                                }
5877                                                        }
5878                                                }
5879                                                
5880                                        } else {
5881                                                TableColumn variableProperty = null;
5882                                                if (stmt.getVariableNames().size() == 1) {
5883                                                        if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
5884                                                                TObjectName starColumn = new TObjectName();
5885                                                                starColumn.setString("*");
5886                                                                variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
5887                                                        } else {
5888                                                                variableProperty = cursorVariable.getColumns().get(0);
5889                                                        }
5890                                                } else {
5891                                                        variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true);
5892                                                }
5893
5894                                                if (stmt.getCursorName() != null) {
5895                                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5896                                                        String variableString = stmt.getCursorName().toString();
5897                                                        if (variableString.startsWith(":")) {
5898                                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5899                                                        }
5900                                                        if (!SQLUtil.isEmpty(procedureName)) {
5901                                                                variableString = procedureName + "."
5902                                                                                + SQLUtil.getIdentifierNormalTableName(variableString);
5903                                                        }
5904                                                        Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
5905                                                        if (cursor != null) {
5906                                                                for (int j = 0; j < cursor.getColumns().size(); j++) {
5907                                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5908                                                                        dataflowRelation.setEffectType(EffectType.cursor);
5909                                                                        if (stmt.getVariableNames().size() == 1) {
5910                                                                                dataflowRelation.addSource(
5911                                                                                                new TableColumnRelationshipElement(cursor.getColumns().get(j)));
5912                                                                        } else {
5913                                                                                dataflowRelation.addSource(
5914                                                                                                new TableColumnRelationshipElement(cursor.getColumns().get(j), i));
5915                                                                        }
5916                                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5917                                                                }
5918                                                        }
5919                                                }
5920                                        }
5921                                }
5922                        }
5923                }
5924        }
5925
5926        private void analyzeFetchStmt(TMssqlFetch stmt) {
5927                if (stmt.getVariableNames() != null) {
5928                        for (int i = 0; i < stmt.getVariableNames().size(); i++) {
5929                                TObjectName columnObject = stmt.getVariableNames().getObjectName(i);
5930                                Variable cursorVariable = modelFactory.createVariable(columnObject);
5931                                cursorVariable.setCreateTable(true);
5932                                cursorVariable.setSubType(SubType.record);
5933                                TableColumn variableProperty = null;
5934                                if (stmt.getVariableNames().size() == 1) {
5935                                        if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
5936                                                TObjectName starColumn = new TObjectName();
5937                                                starColumn.setString("*");
5938                                                variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
5939                                        } else {
5940                                                variableProperty = cursorVariable.getColumns().get(0);
5941                                        }
5942                                } else {
5943                                        variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true);
5944                                }
5945
5946                                if (stmt.getCursorName() != null) {
5947                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5948                                        String variableString = stmt.getCursorName().toString();
5949                                        if (variableString.startsWith(":")) {
5950                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5951                                        }
5952                                        if (!SQLUtil.isEmpty(procedureName)) {
5953                                                variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
5954                                        }
5955                                        Table cursor = modelManager
5956                                                        .getTableByName(DlineageUtil.getTableFullName(variableString));
5957                                        if (cursor != null) {
5958                                                for (int j = 0; j < cursor.getColumns().size(); j++) {
5959                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5960                                                        dataflowRelation.setEffectType(EffectType.cursor);
5961                                                        if (stmt.getVariableNames().size() == 1) {
5962                                                                dataflowRelation
5963                                                                                .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j)));
5964                                                        } else {
5965                                                                dataflowRelation
5966                                                                                .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j), i));
5967                                                        }
5968                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5969                                                }
5970                                        }
5971                                }
5972                        }
5973
5974                }
5975        }
5976
5977        private void analyzeLoopStmt(TLoopStmt stmt) {
5978
5979                if (stmt.getCursorName() != null && stmt.getIndexName() != null) {
5980                        modelManager.bindCursorIndex(stmt.getIndexName(), stmt.getCursorName());
5981                }
5982
5983                if (stmt.getRecordName() != null && stmt.getSubquery() != null) {
5984                        Variable cursorTempTable = modelFactory.createCursor(stmt);
5985                        cursorTempTable.setVariable(true);
5986                        cursorTempTable.setSubType(SubType.cursor);
5987                        modelManager.bindCursorModel(stmt, cursorTempTable);
5988                        analyzeSelectStmt(stmt.getSubquery());
5989
5990                        TableColumn cursorColumn = null;
5991                        if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
5992                                TObjectName starColumn = new TObjectName();
5993                                starColumn.setString("*");
5994                                cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
5995                        } else {
5996                                cursorColumn = cursorTempTable.getColumns().get(0);
5997                        }
5998
5999
6000                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6001                        if (resultSetModel != null) {
6002                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6003                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6004                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6005                                        dataflowRelation.setEffectType(EffectType.cursor);
6006                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6007                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6008                                }
6009                        }
6010                }
6011
6012                for (int i = 0; i < stmt.getStatements().size(); i++) {
6013                        analyzeCustomSqlStmt(stmt.getStatements().get(i));
6014                }
6015        }
6016
6017        private void analyzeForStmt(TForStmt stmt) {
6018                if (stmt.getSubquery() == null) {
6019                        return;
6020                }
6021
6022                Variable cursorTempTable = modelFactory.createCursor(stmt);
6023                cursorTempTable.setVariable(true);
6024                cursorTempTable.setSubType(SubType.cursor);
6025                cursorTempTable.setCreateTable(true);
6026                modelManager.bindCursorModel(stmt, cursorTempTable);
6027                analyzeSelectStmt(stmt.getSubquery());
6028
6029                TableColumn cursorColumn = null;
6030                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6031                        TObjectName starColumn = new TObjectName();
6032                        starColumn.setString("*");
6033                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6034                } else {
6035                        cursorColumn = cursorTempTable.getColumns().get(0);
6036                }
6037
6038
6039                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6040                if (resultSetModel != null) {
6041                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6042                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6043                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6044                                dataflowRelation.setEffectType(EffectType.cursor);
6045                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6046                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6047                        }
6048                }
6049
6050                if (stmt.getStatements() != null && stmt.getStatements().size() > 0) {
6051                        for (int i = 0; i < stmt.getStatements().size(); i++) {
6052                                analyzeCustomSqlStmt(stmt.getStatements().get(i));
6053                        }
6054                }
6055        }
6056
6057        private void analyzeVarDeclStmt(TVarDeclStmt stmt) {
6058                TTypeName typeName = stmt.getDataType();
6059                if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) {
6060                        Variable cursorVariable = modelFactory.createVariable(stmt.getElementName());
6061                        cursorVariable.setSubType(SubType.record_type);
6062
6063                        Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false);
6064                        if(!variableTable.isCreateTable()) {
6065                                TObjectName starColumn1 = new TObjectName();
6066                                starColumn1.setString("*");
6067                                TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true);
6068                                variableTableStarColumn.setShowStar(false);
6069                                variableTableStarColumn.setExpandStar(true);
6070
6071                                TObjectName starColumn = new TObjectName();
6072                                starColumn.setString("*");
6073                                TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
6074                                variableProperty.setShowStar(false);
6075                                variableProperty.setExpandStar(true);
6076
6077                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6078                                dataflowRelation.setEffectType(EffectType.rowtype);
6079                                dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn));
6080                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
6081                        } else {
6082                                for (TableColumn sourceColumn : variableTable.getColumns()) {
6083                                        String columnName = sourceColumn.getName();
6084                                        TObjectName targetColumn = new TObjectName();
6085                                        targetColumn.setString(columnName);
6086                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true);
6087                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6088                                        dataflowRelation.setEffectType(EffectType.rowtype);
6089                                        dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn));
6090                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
6091                                }
6092                        }
6093                } else if (stmt.getElementName() != null) {
6094                        Variable variable = modelFactory.createVariable(stmt.getElementName());
6095                        variable.setCreateTable(true);
6096                        variable.setSubType(SubType.record);
6097                        TableColumn tableColumn = null;
6098                        if (stmt.getDataType() != null && (modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false)!=null || isCursorType(stmt.getDataType().getDataTypeName()))) {
6099                                Variable cursorVariable = modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false);
6100                                if (cursorVariable != null) {
6101                                        if (cursorVariable.getSubType() == SubType.record_type) {
6102                                                variable.setSubType(SubType.record_type);
6103                                        }
6104                                        if(cursorVariable.isDetermined()) {
6105                                                for (int k = 0; k < cursorVariable.getColumns().size(); k++) {
6106                                                        TableColumn sourceColumn = cursorVariable.getColumns().get(k);
6107                                                        TObjectName objectName = new TObjectName();
6108                                                        objectName.setString(sourceColumn.getName());
6109                                                        tableColumn = modelFactory.createTableColumn(variable, objectName, true);
6110                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6111                                                        dataflowRelation.setEffectType(EffectType.cursor);
6112                                                        dataflowRelation
6113                                                                        .addSource(new TableColumnRelationshipElement(sourceColumn));
6114                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
6115                                                }
6116                                                variable.setDetermined(true);
6117                                                return;
6118                                        }
6119                                        else {
6120                                                TObjectName objectName = new TObjectName();
6121                                                objectName.setString("*");
6122                                                tableColumn = modelFactory.createTableColumn(variable, objectName, true);
6123                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6124                                                dataflowRelation.setEffectType(EffectType.cursor);
6125                                                dataflowRelation
6126                                                                .addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
6127                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
6128                                        }
6129                                }
6130                                else {
6131                                        TObjectName objectName = new TObjectName();
6132                                        objectName.setString("*");
6133                                        tableColumn = modelFactory.createTableColumn(variable, objectName, true);                                       
6134                                }
6135                        } else {
6136                                tableColumn = modelFactory.createTableColumn(variable, stmt.getElementName(), true);
6137                                tableColumn.setVariant(true);
6138                        }
6139
6140                        if (stmt.getDefaultValue() != null) {
6141                                columnsInExpr visitor = new columnsInExpr();
6142                                stmt.getDefaultValue().inOrderTraverse(visitor);
6143                                List<TObjectName> objectNames = visitor.getObjectNames();
6144                                List<TParseTreeNode> functions = visitor.getFunctions();
6145                                List<TParseTreeNode> constants = visitor.getConstants();
6146                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6147
6148                                if (functions != null && !functions.isEmpty()) {
6149                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6150                                }
6151                                if (subquerys != null && !subquerys.isEmpty()) {
6152                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6153                                }
6154                                if (objectNames != null && !objectNames.isEmpty()) {
6155                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6156                                }
6157                                if (constants != null && !constants.isEmpty()) {
6158                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6159                                }
6160                        }
6161                        
6162                        
6163                }
6164        }
6165
6166        private boolean isCursorType(String dataTypeName) {
6167                if (dataTypeName != null && dataTypeName.toLowerCase().contains("cursor")) {
6168                        return true;
6169                }
6170                return false;
6171        }
6172
6173        private void analyzeSetStmt(TSetStmt stmt) {
6174                TExpression right = stmt.getVariableValue();
6175                TObjectName columnObject = stmt.getVariableName();
6176                if (columnObject != null) {
6177                        TableColumn tableColumn = null;
6178                        Variable tableModel;
6179                        if (columnObject.toString().indexOf(".") != -1) {
6180                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6181                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6182                        } else {
6183                                tableModel = modelFactory.createVariable(columnObject);
6184                        }
6185                        tableModel.setCreateTable(true);
6186                        tableModel.setSubType(SubType.record);
6187
6188                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6189                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6190                        } else {
6191                                tableColumn = tableModel.getColumns().get(0);
6192                        }
6193
6194                        if (tableColumn != null && right!=null) {
6195                                columnsInExpr visitor = new columnsInExpr();
6196                                right.inOrderTraverse(visitor);
6197                                List<TObjectName> objectNames = visitor.getObjectNames();
6198                                List<TParseTreeNode> functions = visitor.getFunctions();
6199                                List<TParseTreeNode> constants = visitor.getConstants();
6200                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6201
6202                                if (functions != null && !functions.isEmpty()) {
6203                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6204                                }
6205                                if (subquerys != null && !subquerys.isEmpty()) {
6206                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6207                                }
6208                                if (objectNames != null && !objectNames.isEmpty()) {
6209                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6210                                }
6211                                if (constants != null && !constants.isEmpty()) {
6212                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6213                                }
6214                                
6215                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
6216                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
6217                                }
6218                        }
6219                }
6220
6221                if(stmt.getAssignments()!=null){
6222                        for (int i = 0; i < stmt.getAssignments().size(); i++) {
6223                                TSetAssignment assignStmt = stmt.getAssignments().getElement(i);
6224                                analyzeSetAssignmentStmt(assignStmt);
6225                        }
6226                }
6227        }
6228
6229        private void analyzeSetAssignmentStmt(TSetAssignment stmt) {
6230                TExpression right = stmt.getParameterValue();
6231                TObjectName columnObject = stmt.getParameterName();
6232                if (columnObject != null) {
6233                        TableColumn tableColumn = null;
6234                        Variable tableModel;
6235                        if (columnObject.toString().indexOf(".") != -1) {
6236                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6237                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6238                        } else {
6239                                tableModel = modelFactory.createVariable(columnObject);
6240                        }
6241                        tableModel.setCreateTable(true);
6242                        tableModel.setSubType(SubType.record);
6243                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6244                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6245                        } else {
6246                                tableColumn = tableModel.getColumns().get(0);
6247                        }
6248
6249                        if (tableColumn != null && right!=null) {
6250                                columnsInExpr visitor = new columnsInExpr();
6251                                right.inOrderTraverse(visitor);
6252                                List<TObjectName> objectNames = visitor.getObjectNames();
6253                                List<TParseTreeNode> functions = visitor.getFunctions();
6254                                List<TParseTreeNode> constants = visitor.getConstants();
6255                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6256
6257                                if (functions != null && !functions.isEmpty()) {
6258                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6259                                }
6260                                if (subquerys != null && !subquerys.isEmpty()) {
6261                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6262                                }
6263                                if (objectNames != null && !objectNames.isEmpty()) {
6264                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6265                                }
6266                                if (constants != null && !constants.isEmpty()) {
6267                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6268                                }
6269
6270                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
6271                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
6272                                }
6273                        }
6274                }
6275        }
6276
6277        private void analyzeMssqlSetStmt(TMssqlSet stmt) {
6278                TExpression right = stmt.getVarExpr();
6279                TObjectName columnObject = stmt.getVarName();
6280                if (columnObject != null) {
6281                        TableColumn tableColumn = null;
6282                        Variable tableModel;
6283                        if (columnObject.toString().indexOf(".") != -1) {
6284                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6285                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6286                        } else {
6287                                tableModel = modelFactory.createVariable(columnObject);
6288                        }
6289                        tableModel.setCreateTable(true);
6290                        tableModel.setSubType(SubType.record);
6291                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6292                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6293                        }
6294                        else {
6295                                tableColumn = tableModel.getColumns().get(0);
6296                        }
6297
6298                        if (tableColumn != null && right!=null) {
6299                                columnsInExpr visitor = new columnsInExpr();
6300                                right.inOrderTraverse(visitor);
6301                                List<TObjectName> objectNames = visitor.getObjectNames();
6302                                List<TParseTreeNode> functions = visitor.getFunctions();
6303                                List<TParseTreeNode> constants = visitor.getConstants();
6304                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6305
6306                                if (functions != null && !functions.isEmpty()) {
6307                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6308                                }
6309                                if (subquerys != null && !subquerys.isEmpty()) {
6310                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6311                                }
6312                                if (objectNames != null && !objectNames.isEmpty()) {
6313                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6314                                }
6315                                if (constants != null && !constants.isEmpty()) {
6316                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6317                                }
6318
6319                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
6320                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
6321                                }
6322                        }
6323                        else if(tableColumn!=null && stmt.getSubquery()!=null){
6324                                analyzeCustomSqlStmt(stmt.getSubquery());
6325                                analyzeSubqueryDataFlowRelation(tableColumn, Arrays.asList(stmt.getSubquery()), EffectType.select);
6326                        }
6327                }
6328        }
6329
6330        private void analyzeAssignStmt(TAssignStmt stmt) {
6331                TExpression left = stmt.getLeft();
6332                TExpression right = stmt.getExpression();
6333                TObjectName columnObject = null;
6334                if (left == null) {
6335                        columnObject = stmt.getVariableName();
6336                } else if (left.getExpressionType() == EExpressionType.simple_object_name_t) {
6337                        columnObject = left.getObjectOperand();
6338                }
6339                if (columnObject != null) {
6340                        TableColumn tableColumn = null;
6341                        if (columnObject.getDbObjectType() == EDbObjectType.variable || stmt.getVariableName() != null) {
6342                                Variable tableModel;
6343                                if (columnObject.toString().indexOf(".") != -1) {
6344                                        List<String> splits = SQLUtil.parseNames(columnObject.toString());
6345                                        tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6346                                } else {
6347                                        tableModel = modelFactory.createVariable(columnObject);
6348                                }
6349                                tableModel.setCreateTable(true);
6350                                tableModel.setSubType(SubType.record);
6351                                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6352                                        tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6353                                } else {
6354                                        tableColumn = tableModel.getColumns().get(0);
6355                                }
6356                        } else {
6357                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6358                                if (splits.size() > 1) {
6359                                        Table tableModel = modelManager
6360                                                        .getTableByName(DlineageUtil.getTableFullName(splits.get(splits.size() - 2)));
6361                                        if (tableModel == null) {
6362                                                String procedureName = DlineageUtil.getProcedureParentName(stmt);
6363                                                String variableString = splits.get(splits.size() - 2).toString();
6364                                                if (variableString.startsWith(":")) {
6365                                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
6366                                                }
6367                                                if (!SQLUtil.isEmpty(procedureName)) {
6368                                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
6369                                                }
6370                                                tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
6371                                        }
6372                                        if (tableModel != null) {
6373                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6374                                        }
6375                                }
6376                        }
6377
6378                        if (tableColumn != null) {
6379                                Transform transform = new Transform();
6380                                transform.setType(Transform.EXPRESSION);
6381                                transform.setCode(right);
6382                                tableColumn.setTransform(transform);;
6383                                columnsInExpr visitor = new columnsInExpr();
6384                                right.inOrderTraverse(visitor);
6385                                List<TObjectName> objectNames = visitor.getObjectNames();
6386                                List<TParseTreeNode> functions = visitor.getFunctions();
6387                                List<TParseTreeNode> constants = visitor.getConstants();
6388                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6389
6390                                if (functions != null && !functions.isEmpty()) {
6391                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6392                                }
6393                                if (subquerys != null && !subquerys.isEmpty()) {
6394                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6395                                }
6396                                if (objectNames != null && !objectNames.isEmpty()) {
6397                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6398                                }
6399                                if (constants != null && !constants.isEmpty()) {
6400                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6401                                }
6402                        }
6403                }
6404        }
6405
6406        private void analyzeOpenForStmt(TOpenforStmt stmt) {
6407                if (stmt.getSubquery() == null) {
6408                        return;
6409                }
6410
6411                Variable cursorTempTable = modelFactory.createCursor(stmt);
6412                cursorTempTable.setVariable(true);
6413                cursorTempTable.setSubType(SubType.cursor);
6414                modelManager.bindCursorModel(stmt, cursorTempTable);
6415                analyzeSelectStmt(stmt.getSubquery());
6416
6417                TableColumn cursorColumn = null;
6418                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6419                        TObjectName starColumn = new TObjectName();
6420                        starColumn.setString("*");
6421                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6422                } else {
6423                        cursorColumn = cursorTempTable.getColumns().get(0);
6424                }
6425
6426                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6427                if (resultSetModel != null) {
6428                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6429                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6430                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6431                                dataflowRelation.setEffectType(EffectType.cursor);
6432                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6433                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6434                        }
6435                }
6436        }
6437
6438        private void analyzeCursorDeclStmt(TCursorDeclStmt stmt) {
6439                if (stmt.getSubquery() == null) {
6440                        return;
6441                }
6442
6443                Variable cursorTempTable = modelFactory.createCursor(stmt);
6444                cursorTempTable.setVariable(true);
6445                cursorTempTable.setSubType(SubType.cursor);
6446                modelManager.bindCursorModel(stmt, cursorTempTable);
6447                analyzeSelectStmt(stmt.getSubquery());
6448                
6449                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6450                if(resultSetModel!=null && resultSetModel.isDetermined()) {
6451                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6452                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6453                                TObjectName columnName = new TObjectName();
6454                                columnName.setString(resultColumn.getName());
6455                                TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, columnName, true);           
6456                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6457                                dataflowRelation.setEffectType(EffectType.cursor);
6458                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6459                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6460                        }
6461                }
6462                else {
6463                        TableColumn cursorColumn = null;
6464                        if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6465                                TObjectName starColumn = new TObjectName();
6466                                starColumn.setString("*");
6467                                cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6468                        } else {
6469                                cursorColumn = cursorTempTable.getColumns().get(0);
6470                        }
6471                        if (resultSetModel != null) {
6472                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6473                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6474                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6475                                        dataflowRelation.setEffectType(EffectType.cursor);
6476                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6477                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6478                                }
6479                        }
6480                }
6481                
6482        }
6483
6484        private void analyzeDb2Declare(TDb2SqlVariableDeclaration stmt) {
6485                TDeclareVariableList variables = stmt.getVariables();
6486                if (variables == null) {
6487                        return;
6488                }
6489                for (int i = 0; i < variables.size(); i++) {
6490                        TDeclareVariable variable = variables.getDeclareVariable(i);
6491                        if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) {
6492
6493
6494                                TObjectName tableName = variable.getVariableName();
6495                                TTableElementList columns = variable.getTableTypeDefinitions();
6496
6497                                Table tableModel = modelFactory.createTableByName(tableName, true);
6498                                tableModel.setCreateTable(true);
6499                                String procedureParent = getProcedureParentName(stmt);
6500                                if (procedureParent != null) {
6501                                        tableModel.setParent(procedureParent);
6502                                }
6503                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
6504
6505                                for (int j = 0; j < columns.size(); j++) {
6506                                        TTableElement tableElement = columns.getTableElement(j);
6507                                        TColumnDefinition column = tableElement.getColumnDefinition();
6508                                        if (column != null && column.getColumnName() != null) {
6509                                                modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
6510                                        }
6511                                }
6512                        } else if (variable.getVariableName() != null) {
6513                                Variable cursorVariable = modelFactory.createVariable(variable.getVariableName());
6514                                cursorVariable.setCreateTable(true);
6515                                cursorVariable.setSubType(SubType.record);
6516                                if(variable.getDatatype()!=null && isSimpleDataType(variable.getDatatype())){
6517                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable,
6518                                                        variable.getVariableName(), true);
6519                                }
6520                                else {
6521                                        TObjectName variableProperties = new TObjectName();
6522                                        variableProperties.setString("*");
6523                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable,
6524                                                        variableProperties, true);
6525                                }
6526                        }
6527                }
6528        }
6529
6530        private void analyzeMssqlDeclare(TMssqlDeclare stmt) {
6531                if (stmt.getDeclareType() == EDeclareType.variable) {
6532                        TDeclareVariableList variables = stmt.getVariables();
6533                        if (variables == null) {
6534                                return;
6535                        }
6536                        for (int i = 0; i < variables.size(); i++) {
6537                                TDeclareVariable variable = variables.getDeclareVariable(i);
6538                                if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) {
6539
6540
6541                                        TObjectName tableName = variable.getVariableName();
6542                                        TTableElementList columns = variable.getTableTypeDefinitions();
6543
6544                                        Table tableModel = modelFactory.createTableByName(tableName, true);
6545                                        tableModel.setCreateTable(true);
6546                                        String procedureParent = getProcedureParentName(stmt);
6547                                        if (procedureParent != null) {
6548                                                tableModel.setParent(procedureParent);
6549                                        }
6550                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
6551
6552                                        for (int j = 0; j < columns.size(); j++) {
6553                                                TTableElement tableElement = columns.getTableElement(j);
6554                                                TColumnDefinition column = tableElement.getColumnDefinition();
6555                                                if (column != null && column.getColumnName() != null) {
6556                                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
6557                                                }
6558                                        }
6559                                } else if (variable.getVariableName() != null) {
6560                                        Variable cursorVariable = modelFactory.createVariable(variable.getVariableName());
6561                                        cursorVariable.setCreateTable(true);
6562                                        cursorVariable.setSubType(SubType.record);
6563                                        TableColumn variableProperty = null;
6564                                        if (variable.getDatatype() != null && isSimpleDataType(variable.getDatatype())) {
6565                                                variableProperty = modelFactory.createTableColumn(cursorVariable, variable.getVariableName(),
6566                                                                true);
6567                                        } else {
6568                                                TObjectName variableProperties = new TObjectName();
6569                                                variableProperties.setString("*");
6570                                                variableProperty = modelFactory.createTableColumn(cursorVariable, variableProperties, true);
6571                                        }
6572                                        
6573                                        if (variable.getDefaultValue() != null && variable.getDefaultValue().getSubQuery() != null) {
6574                                                analyzeSelectStmt(variable.getDefaultValue().getSubQuery());
6575                                                ResultSet resultSetModel = (ResultSet) modelManager
6576                                                                .getModel(variable.getDefaultValue().getSubQuery());
6577                                                if (variableProperty != null && resultSetModel != null) {
6578                                                        for (ResultColumn column : resultSetModel.getColumns()) {
6579                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6580                                                                dataflowRelation.setEffectType(EffectType.select);
6581                                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(column));
6582                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
6583                                                        }
6584                                                }
6585                                        }
6586                                }
6587                        }
6588                } else if (stmt.getDeclareType() == EDeclareType.cursor) {
6589                        Variable cursorTempTable = modelFactory.createCursor(stmt);
6590                        cursorTempTable.setVariable(true);
6591                        cursorTempTable.setSubType(SubType.cursor);
6592                        modelManager.bindCursorModel(stmt, cursorTempTable);
6593                        analyzeSelectStmt(stmt.getSubquery());
6594                        ResultSet resultSetModel = (ResultSet)modelManager.getModel(stmt.getSubquery());
6595                        if (resultSetModel != null && resultSetModel.isDetermined()) {
6596                                for(ResultColumn resultColumn: resultSetModel.getColumns()){
6597                                        TObjectName starColumn = new TObjectName();
6598                                        starColumn.setString(resultColumn.getName());
6599                                        TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6600                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6601                                        dataflowRelation.setEffectType(EffectType.cursor);
6602                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6603                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6604                                }
6605                        }
6606                        else {
6607                                TableColumn cursorColumn = null;
6608                                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6609                                        TObjectName starColumn = new TObjectName();
6610                                        starColumn.setString("*");
6611                                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6612                                        cursorColumn.setShowStar(false);
6613                                        cursorColumn.setExpandStar(true);
6614                                } else {
6615                                        cursorColumn = cursorTempTable.getColumns().get(0);
6616                                }
6617
6618                                if (resultSetModel != null) {
6619                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6620                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6621                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6622                                                dataflowRelation.setEffectType(EffectType.cursor);
6623                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6624                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6625                                        }
6626                                }
6627                        }
6628                }
6629        }
6630
6631
6632        private boolean analyzeMssqlJsonDeclare(TMssqlDeclare stmt, String jsonName, Table jsonTable) {
6633                TDeclareVariableList variables = stmt.getVariables();
6634                if (variables == null) {
6635                        return false;
6636                }
6637                for (int i = 0; i < variables.size(); i++) {
6638                        TDeclareVariable variable = variables.getDeclareVariable(i);
6639                        TObjectName variableName = variable.getVariableName();
6640                        if (DlineageUtil.getIdentifierNormalTableName(variableName.toString())
6641                                        .equals(DlineageUtil.getIdentifierNormalTableName(jsonName))) {
6642                                if (variable.getDefaultValue() != null) {
6643                                        Table variableTable = modelFactory.createJsonVariable(variableName);
6644                                        variableTable.setVariable(true);
6645                                        variableTable.setSubType(SubType.scalar);
6646                                        variableTable.setCreateTable(true);
6647                                        TableColumn property = modelFactory.createVariableProperty(variableTable, variable);
6648
6649                                        for (int j = 0; j < jsonTable.getColumns().size(); j++) {
6650                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6651                                                relation.setEffectType(EffectType.select);
6652                                                relation.setTarget(new TableColumnRelationshipElement(jsonTable.getColumns().get(j)));
6653                                                relation.addSource(new TableColumnRelationshipElement(property));
6654                                        }
6655                                }
6656                                return true;
6657                        }
6658                }
6659                return false;
6660        }
6661
6662        private void analyzeCreateTableStmt(TCreateTableSqlStatement stmt) {
6663                if (stmt.getCloneSourceTable() != null) {
6664                        analyzeCloneTableStmt(stmt);
6665                        return;
6666                }
6667
6668                TTable table = stmt.getTargetTable();
6669
6670                boolean hasDefinition = false;
6671
6672                if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
6673                        hasDefinition = true;
6674                }
6675
6676                if (table != null) {
6677                        Table tableModel = modelFactory.createTableFromCreateDDL(table, hasDefinition || stmt.getSubQuery() == null
6678                                        || (stmt.getSubQuery().getSetOperatorType() == ESetOperatorType.none && stmt.getSubQuery().getResultColumnList().toString().indexOf("*") == -1));
6679                        if (stmt.isExternal()) {
6680                                tableModel.setExternal(true);
6681                        }
6682
6683                        if (stmt.getSubQuery() != null) {
6684                                Process process = modelFactory.createProcess(stmt);
6685                                tableModel.addProcess(process);
6686                        }
6687
6688                        String procedureParent = getProcedureParentName(stmt);
6689                        if (procedureParent != null) {
6690                                tableModel.setParent(procedureParent);
6691                        }
6692
6693                        if (hasDefinition) {
6694                                if(stmt.getSubQuery()!=null) {
6695                                        TSelectSqlStatement subquery = stmt.getSubQuery();
6696                                        analyzeSelectStmt(subquery);
6697                                        Process process = modelFactory.createProcess(stmt);
6698                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
6699                                        if(resultSetModel.isDetermined()){
6700                                                tableModel.setFromDDL(true);
6701                                        }
6702                                        if (resultSetModel != null) {
6703                                                int resultSetSize = resultSetModel.getColumns().size();
6704                                                int stmtColumnSize = stmt.getColumnList().size();
6705                                                int j = 0;
6706                                                int tableColumnSize = stmtColumnSize;
6707                                                if (resultSetModel.isDetermined() && resultSetSize > tableColumnSize) {
6708                                                        tableColumnSize = resultSetSize;
6709                                                }
6710                                                for (int i = 0; i < tableColumnSize && j < resultSetSize; i++) {
6711                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
6712                                                        if (i < stmtColumnSize) {
6713                                                                TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName();
6714                                                                
6715                                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
6716                                                                        j++;
6717                                                                } else {
6718                                                                        if (resultSetSize - j == stmt.getColumnList().size() - i) {
6719                                                                                j++;
6720                                                                        }
6721                                                                }
6722
6723                                                                if (alias != null) {
6724                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true);
6725                                                                        if (resultColumn != null) {
6726                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6727                                                                                relation.setEffectType(EffectType.create_table);
6728                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6729                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6730                                                                                relation.setProcess(process);
6731                                                                        }
6732                                                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
6733                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel,
6734                                                                                        (TObjectName) resultColumn.getColumnObject(), true);
6735                                                                        if (resultColumn != null) {
6736                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6737                                                                                relation.setEffectType(EffectType.create_table);
6738                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6739                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6740                                                                                relation.setProcess(process);
6741                                                                        }
6742                                                                } else if (resultColumn.getColumnObject() instanceof TResultColumn) {
6743                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel,
6744                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), true);
6745                                                                        ResultColumn column = (ResultColumn) modelManager
6746                                                                                        .getModel(resultColumn.getColumnObject());
6747                                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
6748                                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
6749                                                                        }
6750                                                                        if (resultColumn != null) {
6751                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6752                                                                                relation.setEffectType(EffectType.create_table);
6753                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6754                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6755                                                                                relation.setProcess(process);
6756                                                                        }
6757                                                                }
6758                                                        }
6759                                                        else if(resultSetModel.isDetermined()){
6760                                                                TObjectName tableName = new TObjectName();
6761                                                                tableName.setString(resultColumn.getName());
6762                                                                TableColumn viewColumn = modelFactory.createTableColumn(tableModel, tableName, true);
6763                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6764                                                                relation.setEffectType(EffectType.create_table);
6765                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6766                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6767                                                                relation.setProcess(process);
6768                                                                j++;
6769                                                        }
6770                                                }
6771                                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
6772                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
6773                                                        impactRelation.setEffectType(EffectType.create_table);
6774                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
6775                                                                        resultSetModel.getRelationRows()));
6776                                                        impactRelation.setTarget(
6777                                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
6778                                                }
6779                                        }
6780
6781                                        if (subquery.getResultColumnList() == null && subquery.getValueClause() != null
6782                                                        && subquery.getValueClause().getValueRows().size() == stmt.getColumnList().size()) {
6783                                                for (int i = 0; i < stmt.getColumnList().size(); i++) {
6784                                                        TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName();
6785
6786                                                        if (alias != null) {
6787                                                                TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true);
6788
6789                                                                TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr();
6790
6791                                                                columnsInExpr visitor = new columnsInExpr();
6792                                                                expression.inOrderTraverse(visitor);
6793                                                                List<TObjectName> objectNames = visitor.getObjectNames();
6794                                                                List<TParseTreeNode> functions = visitor.getFunctions();
6795
6796                                                                if (functions != null && !functions.isEmpty()) {
6797                                                                        analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select);
6798
6799                                                                }
6800
6801                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6802                                                                if (subquerys != null && !subquerys.isEmpty()) {
6803                                                                        analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select);
6804                                                                }
6805
6806                                                                analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions);
6807                                                                List<TParseTreeNode> constants = visitor.getConstants();
6808                                                                analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions);
6809                                                        }
6810                                                }
6811                                        }
6812                                        
6813                                        return;
6814                                }
6815                                else {
6816                                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
6817                                                TColumnDefinition column = stmt.getColumnList().getColumn(i);
6818                                                if (column.getDatatype() != null && column.getDatatype().getTypeOfList() != null
6819                                                                && column.getDatatype().getTypeOfList().getColumnDefList() != null) {
6820                                                        for (int j = 0; j < column.getDatatype().getTypeOfList().getColumnDefList().size(); j++) {
6821                                                                TObjectName columnName = new TObjectName();
6822                                                                if (column.getDatatype().getDataType() == EDataType.array_t) {
6823//                                                                      columnName.setString(column.getColumnName().getColumnNameOnly() + ".array."
6824//                                                                                      + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6825//                                                                                                      .getColumnName().getColumnNameOnly());
6826                                                                        columnName.setString(column.getColumnName().getColumnNameOnly() + "."
6827                                                                                        + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6828                                                                                        .getColumnName().getColumnNameOnly());
6829                                                                } else {
6830                                                                        columnName.setString(column.getColumnName().getColumnNameOnly() + "."
6831                                                                                        + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6832                                                                                                        .getColumnName().getColumnNameOnly());
6833                                                                }
6834                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName,
6835                                                                                hasDefinition);
6836                                                                tableColumn.setStruct(true);
6837                                                                tableColumn.setColumnIndex(i);
6838                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6839                                                                
6840                                                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
6841                                                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
6842                                                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
6843                                                                        crudRelationship.setEffectType(EffectType.create_table);
6844                                                                }
6845                                                        }
6846                                                        continue;
6847                                                }
6848                                                if (column.getDatatype() != null && column.getDatatype().getColumnDefList() != null) {
6849                                                        Stack<TColumnDefinition> columnPaths = new Stack<TColumnDefinition>();
6850                                                        flattenStructColumns(hasDefinition, tableModel, column, columnPaths, i);
6851                                                        continue;
6852                                                }
6853                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column.getColumnName(),
6854                                                                hasDefinition);
6855                                                if (tableColumn == null) {
6856                                                        continue;
6857                                                }
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                                                if (column.getDatatype() != null && column.getDatatype().getDataType() == EDataType.variant_t) {
6866                                                        if (tableColumn != null) {
6867                                                                tableColumn.setVariant(true);
6868                                                        }
6869                                                }
6870                                                if (column.getDatatype() != null) {
6871                                                        String dType = column.getDatatype().getDataTypeName();
6872                                                        if ((!SQLUtil.isEmpty(dType)) && (dType.indexOf("_") > 0)) {
6873                                                                dType = dType.split("_")[0];
6874                                                        }
6875                                                        tableColumn.setDataType(dType);
6876                                                }
6877                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6878                                        }
6879                                }
6880                        }
6881
6882                        if (stmt.getExternalTableOption("DATA_SOURCE") != null) {
6883                                String dataSourceName = stmt.getExternalTableOption("DATA_SOURCE");
6884                                Table dataSource = modelManager.getTableByName(DlineageUtil.getTableFullName(dataSourceName));
6885                                if (dataSource != null) {
6886                                        TableColumn dataSourceColumn = dataSource.getColumns().get(0);
6887                                        for (int i = 0; i < tableModel.getColumns().size(); i++) {
6888                                                TableColumn column = tableModel.getColumns().get(i);
6889                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6890                                                relation.setTarget(new TableColumnRelationshipElement(column));
6891                                                relation.addSource(new TableColumnRelationshipElement(dataSourceColumn));
6892
6893                                                appendTableColumnToSQLEnv(tableModel, column);
6894                                        }
6895                                }
6896                        }
6897
6898                        if (stmt.getSubQuery() != null) {
6899
6900                                analyzeSelectStmt(stmt.getSubQuery());
6901
6902                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
6903                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
6904                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
6905                                        impactRelation.setEffectType(EffectType.create_table);
6906                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
6907                                                        resultSetModel.getRelationRows()));
6908                                        impactRelation.setTarget(
6909                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
6910                                }
6911                        }
6912
6913                        if (stmt.getSubQuery() != null && !stmt.getSubQuery().isCombinedQuery()) {
6914                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
6915                                                .getModel(stmt.getSubQuery().getResultColumnList());
6916                                if(resultSetModel.isDetermined()){
6917                                        tableModel.setDetermined(true);
6918                                        tableModel.setFromDDL(true);
6919                                }
6920                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6921                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6922                                        if (resultSetModel.isDetermined() && resultColumn.getName().endsWith("*")) {
6923                                                continue;
6924                                        }
6925
6926                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
6927                                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
6928
6929                                                TAliasClause alias = columnObject.getAliasClause();
6930                                                if (alias != null && alias.getAliasName() != null) {
6931                                                        TableColumn tableColumn = null;
6932                                                        if (!hasDefinition) {
6933                                                                tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(),
6934                                                                                !hasDefinition);
6935                                                        } else {
6936                                                                tableColumn = tableModel.getColumns().get(i);
6937                                                        }
6938
6939                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6940                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6941                                                        }
6942
6943                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6944                                                        relation.setEffectType(EffectType.create_table);
6945                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6946                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6947                                                        Process process = modelFactory.createProcess(stmt);
6948                                                        relation.setProcess(process);
6949                                                } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) {
6950                                                        TableColumn tableColumn = null;
6951                                                        TObjectName columnObj = columnObject.getFieldAttr();
6952                                                        if(columnObj == null) {
6953                                                                columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand();
6954                                                        }
6955                                                        if ((columnObj == null || columnObj.toString().endsWith("*")) && !resultColumn.getName().endsWith("*")) {
6956                                                                columnObj = new TObjectName();
6957                                                                columnObj.setString(resultColumn.getName());
6958                                                        }
6959
6960                                                        if(columnObj == null){
6961                                                                logger.info("Can't handle column " + resultColumn.getName());
6962                                                                continue;
6963                                                        }
6964
6965                                                        if (!hasDefinition) {
6966                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObj,
6967                                                                                !hasDefinition);
6968                                                                if (tableColumn == null) {
6969                                                                        if (tableModel.getColumns().isEmpty()) {
6970                                                                                logger.info("Add table " + tableModel.getName() + " column " + columnObj.toString() + " failed");
6971                                                                        }
6972                                                                        else if (resultColumn.getName().endsWith("*")) {
6973                                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
6974                                                                                        tableColumn = tableModel.getColumns().get(j);
6975                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6976                                                                                        relation.setEffectType(EffectType.create_table);
6977                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6978                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6979                                                                                        if (tableColumn.getName().endsWith("*")
6980                                                                                                        && resultColumn.getName().endsWith("*")) {
6981                                                                                                tableModel.setStarStmt("create_table");
6982                                                                                        }
6983                                                                                        Process process = modelFactory.createProcess(stmt);
6984                                                                                        relation.setProcess(process);
6985                                                                                }
6986                                                                        }
6987                                                                        continue;
6988                                                                }
6989                                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6990                                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
6991                                                                }
6992
6993                                                                Object model = modelManager
6994                                                                                .getModel(resultColumn.getColumnObject());
6995                                                                if (model instanceof ResultColumn) {
6996                                                                        ResultColumn column = (ResultColumn) model;
6997                                                                        if (tableColumn.getName().endsWith("*") && column != null
6998                                                                                        && !column.getStarLinkColumns().isEmpty()) {
6999                                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7000                                                                        }
7001
7002                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7003                                                                        relation.setEffectType(EffectType.create_table);
7004                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7005                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7006                                                                        if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
7007                                                                                tableModel.setStarStmt("create_table");
7008                                                                        }
7009                                                                        Process process = modelFactory.createProcess(stmt);
7010                                                                        relation.setProcess(process);
7011                                                                }
7012                                                                else if(model instanceof LinkedHashMap) {
7013                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
7014                                                                        LinkedHashMap<String, ResultColumn> resultColumns =  (LinkedHashMap<String, ResultColumn>)model;
7015                                                                        if (columnObj.toString().endsWith("*")) {
7016                                                                                for (String key : resultColumns.keySet()) {
7017                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName());
7018                                                                                        DataFlowRelationship relation = modelFactory
7019                                                                                                        .createDataFlowRelation();
7020                                                                                        relation.setEffectType(EffectType.create_table);
7021                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7022                                                                                        relation.addSource(
7023                                                                                                        new ResultColumnRelationshipElement(resultColumns.get(key)));
7024                                                                                        Process process = modelFactory.createProcess(stmt);
7025                                                                                        relation.setProcess(process);
7026                                                                                }
7027                                                                        } else if (resultColumns.containsKey(columnName)) {
7028                                                                                ResultColumn column = resultColumns.get(columnName);
7029                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName());
7030                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7031                                                                                relation.setEffectType(EffectType.create_table);
7032                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7033                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
7034                                                                                Process process = modelFactory.createProcess(stmt);
7035                                                                                relation.setProcess(process);
7036                                                                        }
7037                                                                }
7038                                                        } else {
7039                                                                if (resultColumn.getName().endsWith("*")) {
7040                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
7041                                                                                tableColumn = tableModel.getColumns().get(j);
7042                                                                                ResultColumn column = (ResultColumn) modelManager
7043                                                                                                .getModel(resultColumn.getColumnObject());
7044                                                                                if (tableColumn.getName().endsWith("*") && column != null
7045                                                                                                && !column.getStarLinkColumns().isEmpty()) {
7046                                                                                        tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7047                                                                                }
7048
7049                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7050                                                                                relation.setEffectType(EffectType.create_table);
7051                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7052                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7053                                                                                if (tableColumn.getName().endsWith("*")
7054                                                                                                && resultColumn.getName().endsWith("*")) {
7055                                                                                        tableModel.setStarStmt("create_table");
7056                                                                                        ;
7057                                                                                }
7058                                                                                Process process = modelFactory.createProcess(stmt);
7059                                                                                relation.setProcess(process);
7060                                                                        }
7061                                                                } else {
7062                                                                        tableColumn = tableModel.getColumns().get(i);
7063                                                                        Object model = modelManager
7064                                                                                        .getModel(resultColumn.getColumnObject());
7065                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
7066                                                                        if(model instanceof LinkedHashMap) {
7067                                                                                LinkedHashMap<String, ResultColumn> resultColumns =  (LinkedHashMap<String, ResultColumn>)model;
7068                                                                                if (resultColumns.size() == tableModel.getColumns().size()) {
7069                                                                                        int j = 0;
7070                                                                                        for (String key : resultColumns.keySet()) {
7071                                                                                                if (j == i) {
7072                                                                                                        ResultColumn column = resultColumns.get(key);
7073                                                                                                        DataFlowRelationship relation = modelFactory
7074                                                                                                                        .createDataFlowRelation();
7075                                                                                                        relation.setEffectType(EffectType.create_table);
7076                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7077                                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
7078                                                                                                        Process process = modelFactory.createProcess(stmt);
7079                                                                                                        relation.setProcess(process);
7080                                                                                                }
7081                                                                                                j++;
7082                                                                                        }
7083                                                                                } else if (resultColumns.containsKey(columnName)) {
7084                                                                                        ResultColumn column = resultColumns.get(columnName);
7085                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName());
7086                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7087                                                                                        relation.setEffectType(EffectType.create_table);
7088                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7089                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
7090                                                                                        Process process = modelFactory.createProcess(stmt);
7091                                                                                        relation.setProcess(process);
7092                                                                                } else {
7093                                                                                        throw new UnsupportedOperationException("Can't handle this star case.");
7094                                                                                }
7095                                                                        }
7096                                                                        else if (model instanceof ResultColumn) {
7097                                                                                ResultColumn column = (ResultColumn) modelManager
7098                                                                                                .getModel(resultColumn.getColumnObject());
7099                                                                                if (tableColumn.getName().endsWith("*") && column != null
7100                                                                                                && !column.getStarLinkColumns().isEmpty()) {
7101                                                                                        tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7102                                                                                }
7103
7104                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7105                                                                                relation.setEffectType(EffectType.create_table);
7106                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7107                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7108                                                                                if (tableColumn.getName().endsWith("*")
7109                                                                                                && resultColumn.getName().endsWith("*")) {
7110                                                                                        tableModel.setStarStmt("create_table");
7111                                                                                }
7112                                                                                Process process = modelFactory.createProcess(stmt);
7113                                                                                relation.setProcess(process);
7114                                                                        }
7115                                                                }
7116                                                        }
7117                                                } else {
7118                                                        TableColumn tableColumn = null;
7119                                                        if (!hasDefinition) {
7120                                                                TObjectName columnName = new TObjectName();
7121                                                                columnName.setString(resultColumn.getColumnObject().toString());
7122                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName, !hasDefinition);
7123                                                                if(tableColumn == null){
7124                                                                        continue;
7125                                                                }
7126                                                        } else {
7127                                                                tableColumn = tableModel.getColumns().get(i);
7128                                                        }
7129                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
7130                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
7131                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7132                                                        }
7133
7134                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7135                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7136                                                        }
7137
7138                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7139                                                        relation.setEffectType(EffectType.create_table);
7140                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7141                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7142                                                        Process process = modelFactory.createProcess(stmt);
7143                                                        relation.setProcess(process);
7144                                                }
7145                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
7146                                                TableColumn tableColumn = null;
7147                                                if (!hasDefinition) {
7148                                                        tableColumn = modelFactory.createTableColumn(tableModel,
7149                                                                        (TObjectName) resultColumn.getColumnObject(), !hasDefinition);
7150                                                } else {
7151                                                        tableColumn = tableModel.getColumns().get(i);
7152                                                }
7153
7154                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7155                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
7156                                                }
7157
7158                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7159                                                relation.setEffectType(EffectType.create_table);
7160                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7161                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7162                                                Process process = modelFactory.createProcess(stmt);
7163                                                relation.setProcess(process);
7164                                        }
7165                                }
7166                        } else if (stmt.getSubQuery() != null) {
7167                                SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(stmt.getSubQuery());
7168                                if(resultSetModel.isDetermined()){
7169                                        tableModel.setDetermined(true);
7170                                        tableModel.setFromDDL(true);
7171                                }
7172                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
7173                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
7174                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
7175                                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
7176
7177                                                TAliasClause alias = columnObject.getAliasClause();
7178                                                if (alias != null && alias.getAliasName() != null) {
7179                                                        TableColumn tableColumn = null;
7180                                                        if (!hasDefinition) {
7181                                                                tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(),
7182                                                                                !hasDefinition);
7183                                                                if (tableColumn == null) {
7184                                                                        continue;
7185                                                                }
7186                                                        } else {
7187                                                                tableColumn = tableModel.getColumns().get(i);
7188                                                        }
7189
7190                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7191                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7192                                                        }
7193
7194                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7195                                                        relation.setEffectType(EffectType.create_table);
7196                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7197                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7198                                                        Process process = modelFactory.createProcess(stmt);
7199                                                        relation.setProcess(process);
7200                                                } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) {
7201                                                        TableColumn tableColumn = null;
7202                                                        TObjectName columnObj = columnObject.getFieldAttr();
7203                                                        if(columnObj == null) {
7204                                                                columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand();
7205                                                        }
7206                                                        if (!hasDefinition) {
7207                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObj,
7208                                                                                !hasDefinition);
7209                                                                if (tableColumn == null) {
7210                                                                        continue;
7211                                                                }
7212                                                        } else {
7213                                                                tableColumn = tableModel.getColumns().get(i);
7214                                                        }
7215                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
7216                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
7217                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7218                                                        }
7219
7220                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7221                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7222                                                        }
7223
7224                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7225                                                        relation.setEffectType(EffectType.create_table);
7226                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7227                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7228                                                        Process process = modelFactory.createProcess(stmt);
7229                                                        relation.setProcess(process);
7230                                                } else {
7231                                                        ErrorInfo errorInfo = new ErrorInfo();
7232                                                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7233                                                        errorInfo.setErrorMessage("Can't handle the table column " + columnObject.toString());
7234                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(
7235                                                                        columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo,
7236                                                                        ModelBindingManager.getGlobalHash()));
7237                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo,
7238                                                                        columnObject.getEndToken().columnNo + columnObject.getEndToken().getAstext().length(),
7239                                                                        ModelBindingManager.getGlobalHash()));
7240                                                        errorInfos.add(errorInfo);
7241                                                        continue;
7242                                                }
7243                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
7244                                                TableColumn tableColumn = null;
7245                                                if (!hasDefinition) {
7246                                                        tableColumn = modelFactory.createTableColumn(tableModel,
7247                                                                        (TObjectName) resultColumn.getColumnObject(), !hasDefinition);
7248                                                } else {
7249                                                        tableColumn = tableModel.getColumns().get(i);
7250                                                }
7251
7252                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7253                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
7254                                                }
7255
7256                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7257                                                relation.setEffectType(EffectType.create_table);
7258                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7259                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7260                                                Process process = modelFactory.createProcess(stmt);
7261                                                relation.setProcess(process);
7262                                        }
7263                                }
7264                        } else if (stmt.getLikeTableName() != null) {
7265                                Table likeTableModel = modelFactory.createTableByName(stmt.getLikeTableName());
7266
7267                                if(likeTableModel.isCreateTable()){
7268                                        for(TableColumn column: likeTableModel.getColumns()){
7269                                                TObjectName tableColumn = new TObjectName();
7270                                                tableColumn.setString(column.getName());
7271                                                TableColumn createTableColumn = modelFactory.createTableColumn(tableModel, tableColumn, true);
7272                                                createTableColumn.setPrimaryKey(column.getPrimaryKey());
7273                                                createTableColumn.setForeignKey(column.getForeignKey());
7274                                                createTableColumn.setIndexKey(column.getIndexKey());
7275                                                createTableColumn.setUnqiueKey(column.getUnqiueKey());
7276                                                createTableColumn.setDataType(column.getDataType());
7277                                        }
7278                                        tableModel.setCreateTable(true);
7279                                }
7280
7281//                              Process process = modelFactory.createProcess(stmt);
7282//                              process.setType("Like Table");
7283//                              tableModel.addProcess(process);
7284//
7285//
7286//                              DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7287//                              relation.setEffectType(EffectType.like_table);
7288//                              relation.setTarget(
7289//                                              new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
7290//                              relation.addSource(
7291//                                              new RelationRowsRelationshipElement<TableRelationRows>(likeTableModel.getRelationRows()));
7292//                              relation.setProcess(process);
7293                        }
7294
7295                        if (stmt.getStageLocation() != null && stmt.getStageLocation().getStageName() != null) {
7296                                tableModel
7297                                                .setLocation(DlineageUtil.getTableFullName(stmt.getStageLocation().getStageName().toString()));
7298                                Process process = modelFactory.createProcess(stmt);
7299                                process.setType("Create External Table");
7300                                tableModel.addProcess(process);
7301                                Table stage = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getLocation()));
7302                                if (stage == null) {
7303                                        stage = modelManager.getTableByName(
7304                                                        DlineageUtil.getTableFullName(stmt.getStageLocation().toString().replaceFirst("@", "")));
7305                                }
7306                                if (stage == null) {
7307                                        stage = modelFactory.createTableByName(stmt.getStageLocation().toString().replaceFirst("@", ""),
7308                                                        false);
7309                                        stage.setCreateTable(false);
7310                                        stage.setStage(true);
7311                                        if (stmt.getStageLocation().getPath() != null) {
7312                                                stage.setLocation(stmt.getStageLocation().getPath().toString());
7313                                                TObjectName location = new TObjectName();
7314                                                location.setString(stmt.getStageLocation().getPath().toString());
7315                                                modelFactory.createStageLocation(stage, location);
7316                                        } else if (stmt.getRegex_pattern() != null) {
7317                                                stage.setLocation(stmt.getRegex_pattern());
7318                                                TObjectName location = new TObjectName();
7319                                                location.setString(stmt.getRegex_pattern());
7320                                                modelFactory.createStageLocation(stage, location);
7321                                        } else {
7322                                                stage.setLocation("unknownPath");
7323                                                TObjectName location = new TObjectName();
7324                                                location.setString("unknownPath");
7325                                                modelFactory.createStageLocation(stage, location);
7326                                        }
7327                                }
7328                                if (stage != null && !stage.getColumns().isEmpty()) {
7329                                        if (!tableModel.getColumns().isEmpty()) {
7330                                                for (int i = 0; i < tableModel.getColumns().size(); i++) {
7331                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7332                                                        relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
7333                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
7334                                                        relation.setProcess(process);
7335                                                }
7336                                        } else {
7337                                                TObjectName starColumn = new TObjectName();
7338                                                starColumn.setString("*");
7339                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
7340                                                tableColumn.setExpandStar(false);
7341                                                tableColumn.setShowStar(true);
7342                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7343                                                relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
7344                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7345                                                relation.setProcess(process);
7346                                        }
7347                                }
7348                        } else if (stmt.getTableOptions() != null && !stmt.getTableOptions().isEmpty()) {
7349                                for (int i = 0; i < stmt.getTableOptions().size(); i++) {
7350                                        TCreateTableOption createTableOption = stmt.getTableOptions().get(i);
7351                                        if (createTableOption.getCreateTableOptionType() != ECreateTableOption.etoBigQueryExternal)
7352                                                continue;
7353                                        List<String> uris = createTableOption.getUris();
7354                                        if (uris == null || uris.isEmpty())
7355                                                continue;
7356                                        Process process = modelFactory.createProcess(stmt);
7357                                        process.setType("Create External Table");
7358                                        tableModel.addProcess(process);
7359                                        if (tableModel.getColumns().isEmpty()) {
7360                                                TObjectName starColumn = new TObjectName();
7361                                                starColumn.setString("*");
7362                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
7363                                                tableColumn.setExpandStar(false);
7364                                                tableColumn.setShowStar(true);
7365                                        }
7366                                        for (String uri : uris) {
7367                                                Table uriFile = modelFactory.createTableByName(uri, true);
7368                                                uriFile.setPath(true);
7369                                                uriFile.setFileFormat(createTableOption.getFormat());
7370                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
7371                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7372                                                        if (stmt.getColumnList() != null) {
7373                                                                TObjectName fileUri = new TObjectName();
7374                                                                fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString());
7375                                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7376                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7377                                                        } else {
7378                                                                TObjectName fileUri = new TObjectName();
7379                                                                fileUri.setString("*");
7380                                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7381                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7382                                                        }
7383                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
7384                                                        relation.setProcess(process);
7385                                                }
7386                                                if (tableModel.getColumns().isEmpty()) {
7387                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7388                                                        TObjectName fileUri = new TObjectName();
7389                                                        fileUri.setString("*");
7390                                                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7391                                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7392                                                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
7393                                                                        tableModel.getRelationRows()));
7394                                                        relation.setProcess(process);
7395                                                }
7396                                        }
7397                                }
7398                        } else if (stmt.getSubQuery() == null && stmt.getTableLocation() != null) {
7399                                Process process = modelFactory.createProcess(stmt);
7400                                process.setType("Create External Table");
7401                                tableModel.addProcess(process);
7402                                Table uriFile = modelFactory.createTableByName(stmt.getTableLocation(), true);
7403                                uriFile.setPath(true);
7404                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
7405                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7406                                        if (stmt.getColumnList() != null) {
7407                                                TObjectName fileUri = new TObjectName();
7408                                                fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString());
7409                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7410                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7411                                        } else {
7412                                                TObjectName fileUri = new TObjectName();
7413                                                fileUri.setString("*");
7414                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7415                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7416                                        }
7417                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
7418                                        relation.setProcess(process);
7419                                }
7420                        }
7421
7422                        if (stmt.getTableConstraints() != null && stmt.getTableConstraints().size() > 0) {
7423                                for (int i = 0; i < stmt.getTableConstraints().size(); i++) {
7424                                        TConstraint createTableConstraint = stmt.getTableConstraints().getConstraint(i);
7425                                        TPTNodeList<TColumnWithSortOrder> keyNames = createTableConstraint.getColumnList();
7426                                        if (keyNames != null) {
7427                                                for (int k = 0; k < keyNames.size(); k++) {
7428                                                        TObjectName keyName = keyNames.getElement(k).getColumnName();
7429                                                        TObjectName referencedTableName = createTableConstraint.getReferencedObject();
7430                                                        TObjectNameList referencedTableColumns = createTableConstraint.getReferencedColumnList();
7431
7432                                                        TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
7433                                                        if (createTableConstraint.getConstraint_type() == EConstraintType.primary_key) {
7434                                                                tableConstraint.setPrimaryKey(true);
7435                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.table_index) {
7436                                                                tableConstraint.setIndexKey(true);
7437                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.unique) {
7438                                                                tableConstraint.setUnqiueKey(true);
7439                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
7440                                                                tableConstraint.setForeignKey(true);
7441                                                                Table referencedTable = modelManager
7442                                                                                .getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
7443                                                                if (referencedTable == null) {
7444                                                                        referencedTable = modelFactory.createTableByName(referencedTableName);
7445                                                                }
7446
7447                                                                if (referencedTableColumns != null) {
7448                                                                        for (int j = 0; j < referencedTableColumns.size(); j++) {
7449                                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
7450                                                                                                referencedTableColumns.getObjectName(j), false);
7451                                                                                if (tableColumn != null) {
7452                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7453                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
7454                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
7455                                                                                        relation.setEffectType(EffectType.foreign_key);
7456                                                                                        Process process = modelFactory.createProcess(stmt);
7457                                                                                        relation.setProcess(process);
7458                                                                                        if (this.option.isShowERDiagram()) {
7459                                                                                                ERRelationship erRelation = modelFactory.createERRelation();
7460                                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
7461                                                                                                erRelation
7462                                                                                                                .setTarget(new TableColumnRelationshipElement(tableConstraint));
7463                                                                                        }
7464                                                                                }
7465                                                                        }
7466                                                                }
7467                                                        }
7468                                                }
7469                                        }
7470                                }
7471                        }
7472
7473                        if (stmt.getHiveTablePartition() != null && stmt.getHiveTablePartition().getColumnDefList() != null) {
7474                                for (int i = 0; i < stmt.getHiveTablePartition().getColumnDefList().size(); i++) {
7475                                        TColumnDefinition column = stmt.getHiveTablePartition().getColumnDefList().getColumn(i);
7476                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
7477                                        appendTableColumnToSQLEnv(tableModel, column.getColumnName());
7478                                }
7479                        }
7480
7481                } else {
7482                        ErrorInfo errorInfo = new ErrorInfo();
7483                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7484                        errorInfo.setErrorMessage("Can't get target table. CreateTableSqlStatement is " + stmt.toString());
7485                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7486                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7487                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7488                                        stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
7489                                        ModelBindingManager.getGlobalHash()));
7490                        errorInfos.add(errorInfo);
7491                }
7492        }
7493
7494        protected void flattenStructColumns(boolean hasDefinition, Table tableModel, TColumnDefinition column,
7495                        Stack<TColumnDefinition> columnPaths, int index) {
7496                columnPaths.push(column);
7497                for (int j = 0; j < column.getDatatype().getColumnDefList().size(); j++) {
7498                        TColumnDefinition columnDefinition = column.getDatatype().getColumnDefList().getColumn(j);
7499                        if (columnDefinition.getDatatype().getColumnDefList() != null) {
7500                                flattenStructColumns(hasDefinition, tableModel, columnDefinition, columnPaths, index);
7501                        } else {
7502                                TObjectName columnName = new TObjectName();
7503                                columnName.setString(getColumnName(columnPaths, columnDefinition));
7504                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName, hasDefinition);
7505                                tableColumn.setColumnIndex(index);
7506                                tableColumn.setStruct(true);
7507                                
7508                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
7509                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
7510                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
7511                                        crudRelationship.setEffectType(EffectType.create_table);
7512                                }
7513                                
7514                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7515                        }
7516                }
7517                columnPaths.pop();
7518        }
7519
7520        private String getColumnName(Stack<TColumnDefinition> columnPaths, TColumnDefinition column) {
7521                StringBuilder buffer = new StringBuilder();
7522                Iterator<TColumnDefinition> iter = columnPaths.iterator();
7523                while(iter.hasNext()) {
7524                        buffer.append(iter.next().getColumnName().getColumnNameOnly()).append(".");
7525                }
7526                buffer.append(column.getColumnName().getColumnNameOnly());
7527                return buffer.toString();
7528        }
7529
7530        private void appendTableColumnToSQLEnv(Table tableModel, TableColumn tableColumn) {
7531                //tableModel如果非determined,请不要添加到sqlenv里
7532                if (sqlenv != null && tableColumn!=null) {
7533                        TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true);
7534                        if (schema != null) {
7535                                TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
7536                                if (tableColumn.hasStarLinkColumn()) {
7537                                        for (String column : tableColumn.getStarLinkColumnNames()) {
7538                                                tempTable.addColumn(DlineageUtil.getColumnNameOnly(column));
7539                                        }
7540                                } else {
7541                                        tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getName()));
7542                                }
7543                        }
7544                }
7545        }
7546
7547        private void appendTableColumnToSQLEnv(Table tableModel, TObjectName tableColumn) {
7548                if (sqlenv != null) {
7549                        TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true);
7550                        if (schema != null) {
7551                                TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
7552                                tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getColumnNameOnly()));
7553                        }
7554                }
7555        }
7556
7557        private void analyzeCreateStageStmt(TCreateStageStmt stmt) {
7558                TObjectName stageName = stmt.getStageName();
7559
7560                if (stageName != null) {
7561
7562                        Table tableModel = modelFactory.createStage(stageName);
7563                        tableModel.setCreateTable(true);
7564                        tableModel.setStage(true);
7565                        tableModel.setLocation(stmt.getExternalStageURL());
7566
7567                        Process process = modelFactory.createProcess(stmt);
7568                        tableModel.addProcess(process);
7569
7570                        TableColumn locationColumn = null;
7571                        if (stmt.getExternalStageURL() != null) {
7572                                TObjectName location = new TObjectName();
7573                                location.setString(stmt.getExternalStageURL());
7574                                locationColumn = modelFactory.createStageLocation(tableModel, location);
7575
7576                                Table pathModel = modelFactory.createTableByName(stmt.getExternalStageURL(), true);
7577                                pathModel.setPath(true);
7578                                pathModel.setCreateTable(true);
7579                                TObjectName fileUri = new TObjectName();
7580                                fileUri.setString(stmt.getExternalStageURL());
7581                                TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri);
7582
7583                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7584                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7585                                relation.setTarget(new TableColumnRelationshipElement(locationColumn));
7586                                relation.setProcess(process);
7587
7588                        } else {
7589                                for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) {
7590                                        if (temp instanceof TPutStmt) {
7591                                                TPutStmt put = (TPutStmt) temp;
7592                                                TStageLocation stageLocation = put.getStageLocation();
7593                                                if (stageLocation != null && stageLocation.getStageName() != null) {
7594                                                        Table stage = modelManager.getTableByName(
7595                                                                        DlineageUtil.getTableFullName(stageLocation.getStageName().toString()));
7596                                                        if (stage == tableModel) {
7597                                                                TObjectName location = new TObjectName();
7598                                                                if (!SQLUtil.isEmpty(put.getFileName())) {
7599                                                                        location.setString(put.getFileName());
7600                                                                        locationColumn = modelFactory.createStageLocation(tableModel, location);
7601                                                                }
7602                                                                break;
7603                                                        }
7604                                                }
7605                                        }
7606                                }
7607                        }
7608
7609                        String fileFormat = stmt.getFileFormatName();
7610                        if (fileFormat != null) {
7611                                for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) {
7612                                        if (temp instanceof TCreateFileFormatStmt) {
7613                                                TCreateFileFormatStmt fileFormatStmt = (TCreateFileFormatStmt) temp;
7614                                                if (fileFormatStmt.getFileFormatName() != null
7615                                                                && fileFormatStmt.getFileFormatName().toString().equalsIgnoreCase(fileFormat)) {
7616                                                        tableModel.setFileType(fileFormatStmt.getTypeName());
7617                                                        break;
7618                                                }
7619                                        }
7620                                }
7621                        }
7622
7623                        String procedureParent = getProcedureParentName(stmt);
7624                        if (procedureParent != null) {
7625                                tableModel.setParent(procedureParent);
7626                        }
7627
7628                        if (locationColumn != null) {
7629                                List<Table> tables = modelManager.getTablesByName();
7630                                if (tables != null) {
7631                                        for (Table referTable : tables) {
7632                                                if (referTable.getLocation() != null && referTable.getLocation()
7633                                                                .equals(DlineageUtil.getIdentifierNormalTableName(tableModel.getName()))) {
7634                                                        for (int i = 0; i < referTable.getColumns().size(); i++) {
7635                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7636                                                                relation.addSource(new TableColumnRelationshipElement(locationColumn));
7637                                                                relation.setTarget(new TableColumnRelationshipElement(referTable.getColumns().get(i)));
7638                                                        }
7639                                                }
7640                                        }
7641                                }
7642                        }
7643                } else {
7644                        ErrorInfo errorInfo = new ErrorInfo();
7645                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7646                        errorInfo.setErrorMessage("Can't get target table. CreateStageStmt is " + stmt.toString());
7647                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7648                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7649                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7650                                        stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
7651                                        ModelBindingManager.getGlobalHash()));
7652                        errorInfo.fillInfo(this);
7653                        errorInfos.add(errorInfo);
7654                }
7655        }
7656
7657        private void analyzeCreateExternalDataSourceStmt(TCreateExternalDataSourceStmt stmt) {
7658                TObjectName dataSourceName = stmt.getDataSourceName();
7659                String locationUrl = stmt.getOption("LOCATION");
7660                if (dataSourceName != null && locationUrl != null) {
7661                        Table tableModel = modelFactory.createDataSource(dataSourceName);
7662                        tableModel.setCreateTable(true);
7663                        tableModel.setDataSource(true);
7664                        tableModel.setLocation(locationUrl);
7665
7666                        Process process = modelFactory.createProcess(stmt);
7667                        tableModel.addProcess(process);
7668
7669                        TObjectName location = new TObjectName();
7670                        location.setString(locationUrl);
7671                        modelFactory.createTableColumn(tableModel, location, true);
7672
7673                        String procedureParent = getProcedureParentName(stmt);
7674                        if (procedureParent != null) {
7675                                tableModel.setParent(procedureParent);
7676                        }
7677                } else {
7678                        ErrorInfo errorInfo = new ErrorInfo();
7679                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7680                        errorInfo.setErrorMessage("Can't get target table. CreateExternalDataSourceStmt is " + stmt.toString());
7681                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7682                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7683                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7684                                        stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
7685                                        ModelBindingManager.getGlobalHash()));
7686                        errorInfo.fillInfo(this);
7687                        errorInfos.add(errorInfo);
7688                }
7689        }
7690
7691        private void analyzeCreateStreamStmt(TCreateStreamStmt stmt) {
7692                TObjectName streamName = stmt.getStreamName();
7693
7694                if (streamName != null) {
7695                        Table tableModel = modelFactory.createTableByName(stmt.getTableName());
7696                        tableModel.setCreateTable(true);
7697
7698                        Table streamModel = modelFactory.createStream(streamName);
7699                        streamModel.setCreateTable(true);
7700                        streamModel.setStream(true);
7701
7702                        Process process = modelFactory.createProcess(stmt);
7703                        tableModel.addProcess(process);
7704
7705                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7706                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(streamModel.getRelationRows()));
7707                        relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
7708                        relation.setProcess(process);
7709                }
7710        }
7711
7712        private String getProcedureParentName(TCustomSqlStatement stmt) {
7713                if (stmt instanceof TStoredProcedureSqlStatement) {
7714                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
7715                                return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
7716                        }
7717                }
7718
7719                stmt = stmt.getParentStmt();
7720                if (stmt == null)
7721                        return null;
7722
7723        if (stmt instanceof TCommonBlock) {
7724                        if(((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) {
7725                                stmt = (TStoredProcedureSqlStatement)((TCommonBlock) stmt).getBlockBody().getParentObjectName();
7726                        }
7727                }
7728
7729                if (stmt instanceof TStoredProcedureSqlStatement) {
7730                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
7731                                return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
7732                        }
7733                }
7734                if (stmt instanceof TTeradataCreateProcedure) {
7735                        if (((TTeradataCreateProcedure) stmt).getProcedureName() != null) {
7736                                return ((TTeradataCreateProcedure) stmt).getProcedureName().toString();
7737                        }
7738                }
7739
7740                return getProcedureParentName(stmt);
7741        }
7742
7743        private TStoredProcedureSqlStatement getProcedureParent(TCustomSqlStatement stmt) {
7744                if (stmt instanceof TStoredProcedureSqlStatement) {
7745                        return (TStoredProcedureSqlStatement) stmt;
7746                }
7747
7748                stmt = stmt.getParentStmt();
7749                if (stmt == null)
7750                        return null;
7751
7752                if (stmt instanceof TCommonBlock) {
7753                        if (((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) {
7754                                stmt = (TStoredProcedureSqlStatement) ((TCommonBlock) stmt).getBlockBody().getParentObjectName();
7755                        }
7756                }
7757
7758                if (stmt instanceof TStoredProcedureSqlStatement) {
7759                        return ((TStoredProcedureSqlStatement) stmt);
7760                }
7761                if (stmt instanceof TTeradataCreateProcedure) {
7762                        return ((TTeradataCreateProcedure) stmt);
7763                }
7764
7765                return getProcedureParent(stmt);
7766        }
7767
7768        private void analyzeMergeStmt(TMergeSqlStatement stmt) {
7769                Object tableModel;
7770                Process process;
7771                if (stmt.getUsingTable() != null) {
7772                        TTable table = stmt.getTargetTable();
7773                        if(table.getSubquery()!=null) {
7774                                tableModel = modelFactory.createQueryTable(table);
7775                                analyzeSelectStmt(table.getSubquery());
7776                                process = modelFactory.createProcess(stmt);
7777                        }
7778                        else {
7779                                tableModel = modelFactory.createTable(table);
7780                                process = modelFactory.createProcess(stmt);
7781                                ((Table)tableModel).addProcess(process);
7782                        }
7783                        
7784                        for(TTable item: stmt.tables) {
7785                                if(item.getSubquery()!=null) {
7786                                        continue;
7787                                }
7788                                Table tableItemModel = modelFactory.createTable(item);                          
7789                                if (tableItemModel.getColumns() == null || tableItemModel.getColumns().isEmpty()) {
7790                                        tableItemModel.addColumnsFromSQLEnv();
7791                                }
7792                        }
7793
7794                        if (stmt.getUsingTable().getSubquery() != null) {
7795                                QueryTable queryTable = modelFactory.createQueryTable(stmt.getUsingTable());
7796                                analyzeSelectStmt(stmt.getUsingTable().getSubquery());
7797
7798                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getUsingTable().getSubquery());
7799                                
7800                                if (queryTable != null && resultSetModel != null && queryTable != resultSetModel) {
7801                                        if (queryTable.getColumns().size() == resultSetModel.getColumns().size()) {
7802                                                for (int i = 0; i < queryTable.getColumns().size(); i++) {
7803                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7804                                                        relation.setEffectType(EffectType.select);
7805                                                        relation.setTarget(new ResultColumnRelationshipElement(queryTable.getColumns().get(i)));
7806                                                        relation.addSource(new ResultColumnRelationshipElement(resultSetModel.getColumns().get(i)));
7807                                                        relation.setProcess(process);
7808                                                }
7809                                        }
7810                                }
7811                                
7812                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
7813                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
7814                                        impactRelation.setEffectType(EffectType.merge);
7815                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
7816                                                        resultSetModel.getRelationRows()));
7817                                        if (tableModel instanceof Table) {
7818                                                impactRelation.setTarget(
7819                                                                new RelationRowsRelationshipElement<TableRelationRows>(((Table)tableModel).getRelationRows()));
7820                                        }
7821                                        else {
7822                                                impactRelation.setTarget(
7823                                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)tableModel).getRelationRows()));
7824                                        }
7825                                }
7826                        } else {
7827                                if (stmt.getUsingTable().getAliasClause() != null && stmt.getUsingTable().getAliasClause().getColumns() != null && stmt.getUsingTable().getValueClause().getRows()!=null) {
7828                                        Table usingTable = modelFactory.createTableFromCreateDDL(stmt.getUsingTable(), false, stmt.getUsingTable().getAliasName() + stmt.getUsingTable().getTableName());
7829                                        usingTable.setCreateTable(true);
7830                                        usingTable.setSubType(SubType.function);
7831                                        for (int z=0;z<stmt.getUsingTable().getAliasClause().getColumns().size();z++) {
7832                                                TObjectName columnName = stmt.getUsingTable().getAliasClause().getColumns().getObjectName(z);
7833                                                TableColumn tableColumn = modelFactory.createTableColumn(usingTable, columnName, true);
7834                                                TResultColumn resultColumn = stmt.getUsingTable().getValueClause().getRows().get(0).getResultColumn(z);
7835                                                modelManager.bindModel(resultColumn, tableColumn);
7836                                                analyzeResultColumnExpressionRelation(tableColumn, resultColumn.getExpr());                                             }
7837                                }
7838                                else {
7839                                        modelFactory.createTable(stmt.getUsingTable());
7840                                }
7841                        }
7842                
7843
7844                        if (stmt.getWhenClauses() != null && stmt.getWhenClauses().size() > 0) {
7845                                for (int i = 0; i < stmt.getWhenClauses().size(); i++) {
7846                                        TMergeWhenClause clause = stmt.getWhenClauses().getElement(i);
7847                                        if (clause.getCondition() != null) {
7848                                                analyzeFilterCondition(null, clause.getCondition(), null, null, EffectType.merge_when);
7849                                        }
7850                                        if (clause.getUpdateClause() != null) {
7851                                                TResultColumnList columns = clause.getUpdateClause().getUpdateColumnList();
7852                                                if (columns == null || columns.size() == 0)
7853                                                        continue;
7854
7855                                                ResultSet resultSet = modelFactory.createResultSet(clause.getUpdateClause(), false);
7856                                                createPseudoImpactRelation(stmt, resultSet, EffectType.merge_update);
7857
7858                                                for (int j = 0; j < columns.size(); j++) {
7859                                                        TResultColumn resultColumn = columns.getResultColumn(j);
7860                                                        if (resultColumn.getExpr().getLeftOperand()
7861                                                                        .getExpressionType() == EExpressionType.simple_object_name_t) {
7862                                                                TObjectName columnObject = resultColumn.getExpr().getLeftOperand().getObjectOperand();
7863
7864                                                                if (columnObject.getDbObjectType() == EDbObjectType.variable) {
7865                                                                        continue;
7866                                                                }
7867
7868                                                                if (columnObject.getColumnNameOnly().startsWith("@")
7869                                                                                && (option.getVendor() == EDbVendor.dbvmssql
7870                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
7871                                                                        continue;
7872                                                                }
7873
7874                                                                if (columnObject.getColumnNameOnly().startsWith(":")
7875                                                                                && (option.getVendor() == EDbVendor.dbvhana
7876                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
7877                                                                        continue;
7878                                                                }
7879
7880                                                                ResultColumn updateColumn = modelFactory.createMergeResultColumn(resultSet,
7881                                                                                columnObject);
7882
7883                                                                TExpression valueExpression = resultColumn.getExpr().getRightOperand();
7884                                                                if (valueExpression == null)
7885                                                                        continue;
7886
7887                                                                columnsInExpr visitor = new columnsInExpr();
7888                                                                valueExpression.inOrderTraverse(visitor);
7889                                                                List<TObjectName> objectNames = visitor.getObjectNames();
7890                                                                List<TParseTreeNode> functions = visitor.getFunctions();
7891
7892                                                                if (functions != null && !functions.isEmpty()) {
7893                                                                        analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.merge_update);
7894                                                                }
7895
7896                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
7897                                                                if (subquerys != null && !subquerys.isEmpty()) {
7898                                                                        analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.merge_update);
7899                                                                }
7900
7901                                                                analyzeDataFlowRelation(updateColumn, objectNames, EffectType.merge_update, functions);
7902
7903                                                                List<TParseTreeNode> constants = visitor.getConstants();
7904                                                                analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.merge_update,
7905                                                                                functions);
7906
7907                                                                if (tableModel instanceof Table) {
7908                                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel, columnObject,
7909                                                                                        false);
7910
7911                                                                        if (tableColumn != null) {
7912                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7913                                                                                relation.setEffectType(EffectType.merge_update);
7914                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7915                                                                                relation.addSource(new ResultColumnRelationshipElement(updateColumn));
7916                                                                                relation.setProcess(process);
7917                                                                        }
7918                                                                }
7919                                                                else {
7920                                                                        TTable targetTable = stmt.getTargetTable().getSubquery().getTables().getTable(0);
7921                                                                        if (targetTable != null && modelManager.getModel(targetTable) instanceof Table) {
7922                                                                                Table targetTableModel = (Table) modelManager.getModel(targetTable);
7923                                                                                TableColumn tableColumn = modelFactory
7924                                                                                                .createTableColumn((Table) targetTableModel, columnObject, false);
7925                                                                                if (tableColumn != null) {
7926                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7927                                                                                        relation.setEffectType(EffectType.merge_update);
7928                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7929                                                                                        relation.addSource(new ResultColumnRelationshipElement(updateColumn));
7930                                                                                        relation.setProcess(process);
7931                                                                                }
7932                                                                        }
7933                                                                }
7934                                                        }
7935                                                }
7936                                        }
7937                                        if (clause.getInsertClause() != null && tableModel instanceof Table) {
7938                                                TExpression insertValue = clause.getInsertClause().getInsertValue();
7939                                                if (insertValue != null
7940                                                                && insertValue.getExpressionType() == EExpressionType.objectConstruct_t) {
7941                                                        ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false);
7942
7943                                                        createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert);
7944
7945                                                        TObjectConstruct objectConstruct = insertValue.getObjectConstruct();
7946                                                        for (int z = 0; z < objectConstruct.getPairs().size(); z++) {
7947                                                                TPair pair = objectConstruct.getPairs().getElement(z);
7948
7949                                                                if (pair.getKeyName().getExpressionType() == EExpressionType.simple_constant_t) {
7950                                                                        TObjectName columnObject = new TObjectName();
7951                                                                        TConstant constant = pair.getKeyName().getConstantOperand();
7952                                                                        TSourceToken newSt = new TSourceToken(
7953                                                                                        constant.getValueToken().getTextWithoutQuoted());
7954                                                                        columnObject.setPartToken(newSt);
7955                                                                        columnObject.setSourceTable(stmt.getTargetTable());
7956                                                                        columnObject.setStartToken(constant.getStartToken());
7957                                                                        columnObject.setEndToken(constant.getEndToken());
7958
7959                                                                        ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet,
7960                                                                                        columnObject);
7961
7962                                                                        TExpression valueExpression = pair.getKeyValue();
7963                                                                        if (valueExpression == null)
7964                                                                                continue;
7965
7966                                                                        columnsInExpr visitor = new columnsInExpr();
7967                                                                        valueExpression.inOrderTraverse(visitor);
7968                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
7969                                                                        List<TParseTreeNode> functions = visitor.getFunctions();
7970
7971                                                                        if (functions != null && !functions.isEmpty()) {
7972                                                                                analyzeFunctionDataFlowRelation(insertColumn, functions,
7973                                                                                                EffectType.merge_insert);
7974                                                                        }
7975
7976                                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
7977                                                                        if (subquerys != null && !subquerys.isEmpty()) {
7978                                                                                analyzeSubqueryDataFlowRelation(insertColumn, subquerys,
7979                                                                                                EffectType.merge_insert);
7980                                                                        }
7981
7982                                                                        analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert,
7983                                                                                        functions);
7984
7985                                                                        List<TParseTreeNode> constants = visitor.getConstants();
7986                                                                        analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert,
7987                                                                                        functions);
7988
7989                                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel,
7990                                                                                        columnObject, false);
7991
7992                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7993                                                                        relation.setEffectType(EffectType.merge_insert);
7994                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7995                                                                        relation.addSource(new ResultColumnRelationshipElement(insertColumn));
7996                                                                        relation.setProcess(process);
7997                                                                }
7998                                                        }
7999                                                } else {
8000                                                        TObjectNameList columns = clause.getInsertClause().getColumnList();
8001                                                        TResultColumnList values = clause.getInsertClause().getValuelist();
8002                                                        if (values == null || values.size() == 0) {
8003                                                                if (clause.getInsertClause().toString().toLowerCase().indexOf("row") != -1) {
8004                                                                        if (stmt.getUsingTable().getSubquery() != null) {
8005                                                                                ResultSet sourceResultSet = modelFactory.createQueryTable(stmt.getUsingTable());
8006                                                                                TObjectName targetStarColumn = new TObjectName();
8007                                                                                targetStarColumn.setString("*");
8008                                                                                TableColumn targetTableColumn = modelFactory.createTableColumn((Table)tableModel,
8009                                                                                                targetStarColumn, true);
8010                                                                                if (sourceResultSet.getColumns() == null
8011                                                                                                || sourceResultSet.getColumns().isEmpty()) {
8012                                                                                        TObjectName sourceStarColumn = new TObjectName();
8013                                                                                        sourceStarColumn.setString("*");
8014                                                                                        modelFactory.createResultColumn(sourceResultSet, sourceStarColumn);
8015                                                                                }
8016                                                                                for (ResultColumn sourceColumn : sourceResultSet.getColumns()) {
8017                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8018                                                                                        relation.setEffectType(EffectType.merge_insert);
8019                                                                                        relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
8020                                                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
8021                                                                                        relation.setProcess(process);
8022                                                                                }
8023                                                                        } else {
8024                                                                                Table sourceTable = modelFactory.createTable(stmt.getUsingTable());
8025                                                                                TObjectName sourceStarColumn = new TObjectName();
8026                                                                                sourceStarColumn.setString("*");
8027                                                                                TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable,
8028                                                                                                sourceStarColumn, true);
8029                                                                                TObjectName targetStarColumn = new TObjectName();
8030                                                                                targetStarColumn.setString("*");
8031                                                                                TableColumn targetTableColumn = modelFactory.createTableColumn(((Table)tableModel),
8032                                                                                                targetStarColumn, true);
8033                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8034                                                                                relation.setEffectType(EffectType.merge_insert);
8035                                                                                relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
8036                                                                                relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
8037                                                                                relation.setProcess(process);
8038                                                                        }
8039
8040                                                                }
8041                                                                continue;
8042                                                        }
8043
8044                                                        List<TObjectName> tableColumns = new ArrayList<TObjectName>();
8045                                                        if (columns == null || columns.size() == 0) {
8046//                                                              if (!((Table)tableModel).getColumns().isEmpty()) {
8047//                                                                      for (int j = 0; j < ((Table)tableModel).getColumns().size(); j++) {
8048//                                                                              if (((Table)tableModel).getColumns().get(j).getColumnObject() == null) {
8049//                                                                                      continue;
8050//                                                                              }
8051//                                                                              tableColumns.add(((Table)tableModel).getColumns().get(j).getColumnObject());
8052//                                                                      }
8053//                                                              } else {
8054                                                                        for (int j = 0; j < values.size(); j++) {
8055                                                                                TResultColumn column = values.getResultColumn(j);
8056                                                                                if (column.getAliasClause() != null) {
8057                                                                                        tableColumns.add(column.getAliasClause().getAliasName());
8058                                                                                } else if (column.getFieldAttr() != null) {
8059                                                                                        tableColumns.add(column.getFieldAttr());
8060                                                                                } else {
8061                                                                                        TObjectName columnName = new TObjectName();
8062                                                                                        columnName.setString(column.toString());
8063                                                                                        tableColumns.add(columnName);
8064                                                                                }
8065//                                                                      }
8066                                                                }
8067                                                        } else {
8068                                                                for (int j = 0; j < columns.size(); j++) {
8069                                                                        tableColumns.add(columns.getObjectName(j));
8070                                                                }
8071                                                        }
8072
8073                                                        ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false);
8074
8075                                                        createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert);
8076
8077                                                        for (int j = 0; j < tableColumns.size() && j < values.size(); j++) {
8078                                                                TObjectName columnObject = tableColumns.get(j);
8079
8080                                                                ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet,
8081                                                                                columnObject);
8082
8083                                                                TExpression valueExpression = values.getResultColumn(j).getExpr();
8084                                                                if (valueExpression == null)
8085                                                                        continue;
8086
8087                                                                columnsInExpr visitor = new columnsInExpr();
8088                                                                valueExpression.inOrderTraverse(visitor);
8089                                                                List<TObjectName> objectNames = visitor.getObjectNames();
8090                                                                List<TParseTreeNode> functions = visitor.getFunctions();
8091
8092                                                                if (functions != null && !functions.isEmpty()) {
8093                                                                        analyzeFunctionDataFlowRelation(insertColumn, functions, EffectType.merge_insert);
8094                                                                }
8095
8096                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
8097                                                                if (subquerys != null && !subquerys.isEmpty()) {
8098                                                                        analyzeSubqueryDataFlowRelation(insertColumn, subquerys, EffectType.merge_insert);
8099                                                                }
8100
8101                                                                analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert, functions);
8102
8103                                                                List<TParseTreeNode> constants = visitor.getConstants();
8104                                                                analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert,
8105                                                                                functions);
8106
8107                                                                TableColumn tableColumn = modelFactory.createTableColumn(((Table)tableModel), columnObject,
8108                                                                                false);
8109                                                                if(tableColumn == null) {
8110                                                                        if (((Table) tableModel).isCreateTable()) {
8111                                                                                tableColumn = ((Table) tableModel).getColumns().get(j);
8112                                                                        }
8113                                                                        else {
8114                                                                                continue;
8115                                                                        }
8116                                                                }
8117
8118                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8119                                                                relation.setEffectType(EffectType.merge_insert);
8120                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8121                                                                relation.addSource(new ResultColumnRelationshipElement(insertColumn));
8122                                                                relation.setProcess(process);
8123                                                        }
8124                                                }
8125                                        }
8126                                }
8127
8128                        }
8129
8130                        if (stmt.getCondition() != null) {
8131                                analyzeFilterCondition(null, stmt.getCondition(), null, JoinClauseType.on, EffectType.merge);
8132                        }
8133                }
8134        }
8135
8136        private List<TableColumn> bindInsertTableColumn(Table tableModel, TInsertIntoValue value, List<TObjectName> keyMap,
8137                        List<TResultColumn> valueMap) {
8138                List<TableColumn> tableColumns = new ArrayList<TableColumn>();
8139                if (value.getColumnList() != null) {
8140                        for (int z = 0; z < value.getColumnList().size(); z++) {
8141                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8142                                                value.getColumnList().getObjectName(z));
8143                                tableColumns.add(tableColumn);
8144                                keyMap.add(tableColumn.getColumnObject());
8145                        }
8146                }
8147
8148                if (value.getTargetList() != null) {
8149                        for (int z = 0; z < value.getTargetList().size(); z++) {
8150                                TMultiTarget target = value.getTargetList().getMultiTarget(z);
8151                                TResultColumnList columns = target.getColumnList();
8152                                for (int i = 0; i < columns.size(); i++) {
8153                                        if (value.getColumnList() == null) {
8154                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8155                                                                columns.getResultColumn(i).getFieldAttr());
8156                                                tableColumns.add(tableColumn);
8157                                        }
8158                                        valueMap.add(columns.getResultColumn(i));
8159                                }
8160                        }
8161                }
8162
8163                return tableColumns;
8164        }
8165
8166        private TableColumn matchColumn(List<TableColumn> tableColumns, TableColumn targetColumn) {
8167                String columnName = targetColumn.getName();
8168                if (tableColumns == null) {
8169                        return null;
8170                }
8171                for (int i = 0; i < tableColumns.size(); i++) {
8172                        TableColumn column = tableColumns.get(i);
8173                        if (column.getColumnObject() == null) {
8174                                continue;
8175                        }
8176                        if(column.isStruct() && targetColumn.isStruct()) {
8177                                List<String> names = SQLUtil.parseNames(column.getName());
8178                                List<String> targetNames = SQLUtil
8179                                                .parseNames(targetColumn.getName());
8180                                if (!getColumnName(targetNames.get(0))
8181                                                .equals(getColumnName(names.get(0)))) {
8182                                        continue;
8183                                }
8184                        }
8185                        if (getColumnName(column.getColumnObject().toString()).equals(getColumnName(columnName))) {
8186                                return column;
8187                        }
8188                }
8189                return null;
8190        }
8191        
8192        private TableColumn matchColumn(List<TableColumn> tableColumns, TObjectName columnName) {
8193                if (tableColumns == null) {
8194                        return null;
8195                }
8196                for (int i = 0; i < tableColumns.size(); i++) {
8197                        TableColumn column = tableColumns.get(i);
8198                        if (column.getColumnObject() == null) {
8199                                continue;
8200                        }
8201                        if (DlineageUtil.getColumnName(column.getColumnObject()).equalsIgnoreCase(DlineageUtil.getColumnName(columnName)))
8202                                return column;
8203                }
8204                return null;
8205        }
8206
8207        private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, ResultColumn resultColumn) {
8208                if (resultColumns == null) {
8209                        return null;
8210                }
8211
8212                TObjectName columnName = getObjectName(resultColumn);
8213                if (columnName == null) {
8214                        return null;
8215                }
8216
8217                for (int i = 0; i < resultColumns.size(); i++) {
8218                        ResultColumn column = resultColumns.get(i);
8219                        if (column.getAlias() != null
8220                                        && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName)))
8221                                return column;
8222                        if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName)))
8223                                return column;
8224                        if (column.getName() != null && column.getName().endsWith("*")) {
8225                                if ("*".equals(column.getColumnObject().toString())) {
8226                                        return column;
8227                                } else {
8228                                        TObjectName columnObjectName = getObjectName(column);
8229                                        if (columnObjectName.getTableString() != null
8230                                                        && columnObjectName.getTableString().equals(getResultSetAlias(resultColumn))) {
8231                                                return column;
8232                                        }
8233                                }
8234                        }
8235                }
8236                return null;
8237        }
8238
8239        private String getResultSetAlias(ResultColumn resultColumn) {
8240                ResultSet resultSet = resultColumn.getResultSet();
8241                if (resultSet instanceof QueryTable) {
8242                        return ((QueryTable) resultSet).getAlias();
8243                }
8244                return null;
8245        }
8246
8247        private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, TObjectName columnName) {
8248                if (resultColumns == null) {
8249                        return null;
8250                }
8251                for (int i = 0; i < resultColumns.size(); i++) {
8252                        ResultColumn column = resultColumns.get(i);
8253                        if (column.getAlias() != null
8254                                        && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName)))
8255                                return column;
8256                        if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName)))
8257                                return column;
8258                        if (column.getName() != null && column.getName().endsWith("*")) {
8259                                if ("*".equals(column.getColumnObject().toString())) {
8260                                        return column;
8261                                } else {
8262                                        TObjectName columnObjectName = getObjectName(column);
8263                                        if (columnObjectName.getTableString() != null
8264                                                        && columnObjectName.getTableString().equals(columnName.getTableString())) {
8265                                                return column;
8266                                        }
8267                                }
8268                        }
8269                }
8270                return null;
8271        }
8272
8273        private void analyzeInsertStmt(TInsertSqlStatement stmt) {
8274                Map<Table, List<TObjectName>> insertTableKeyMap = new LinkedHashMap<Table, List<TObjectName>>();
8275                Map<Table, List<TResultColumn>> insertTableValueMap = new LinkedHashMap<Table, List<TResultColumn>>();
8276                Map<String, List<TableColumn>> tableColumnMap = new LinkedHashMap<String, List<TableColumn>>();
8277                List<Table> inserTables = new ArrayList<Table>();
8278                List<TExpression> expressions = new ArrayList<TExpression>();
8279                boolean hasInsertColumns = false;
8280                
8281                EffectType effectType = EffectType.insert;
8282                if(stmt.getInsertToken()!=null && stmt.getInsertToken().toString().toLowerCase().startsWith("replace")) {
8283                        effectType = EffectType.replace;
8284                }
8285                
8286                if (stmt.getInsertConditions() != null && stmt.getInsertConditions().size() > 0) {
8287                        for (int i = 0; i < stmt.getInsertConditions().size(); i++) {
8288                                TInsertCondition condition = stmt.getInsertConditions().getElement(i);
8289                                if (condition.getCondition() != null) {
8290                                        expressions.add(condition.getCondition());
8291                                }
8292                                for (int j = 0; j < condition.getInsertIntoValues().size(); j++) {
8293                                        TInsertIntoValue value = condition.getInsertIntoValues().getElement(j);
8294                                        TTable table = value.getTable();
8295                                        Table tableModel = modelFactory.createTable(table);
8296
8297                                        inserTables.add(tableModel);
8298                                        List<TObjectName> keyMap = new ArrayList<TObjectName>();
8299                                        List<TResultColumn> valueMap = new ArrayList<TResultColumn>();
8300                                        insertTableKeyMap.put(tableModel, keyMap);
8301                                        insertTableValueMap.put(tableModel, valueMap);
8302
8303                                        List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap);
8304                                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null
8305                                                        && !tableColumns.isEmpty()) {
8306                                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()),
8307                                                                tableColumns);
8308                                        }
8309
8310                                        // if (stmt.getSubQuery() != null)
8311                                        {
8312                                                Process process = modelFactory.createProcess(stmt);
8313                                                tableModel.addProcess(process);
8314                                        }
8315                                }
8316                        }
8317                        hasInsertColumns = true;
8318                } else if (stmt.getInsertIntoValues() != null && stmt.getInsertIntoValues().size() > 0) {
8319                        for (int i = 0; i < stmt.getInsertIntoValues().size(); i++) {
8320                                TInsertIntoValue value = stmt.getInsertIntoValues().getElement(i);
8321                                TTable table = value.getTable();
8322                                Table tableModel = modelFactory.createTable(table);
8323
8324                                inserTables.add(tableModel);
8325                                List<TObjectName> keyMap = new ArrayList<TObjectName>();
8326                                List<TResultColumn> valueMap = new ArrayList<TResultColumn>();
8327                                insertTableKeyMap.put(tableModel, keyMap);
8328                                insertTableValueMap.put(tableModel, valueMap);
8329
8330                                List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap);
8331                                if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
8332                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
8333                                }
8334
8335                                // if (stmt.getSubQuery() != null)
8336                                {
8337                                        Process process = modelFactory.createProcess(stmt);
8338                                        tableModel.addProcess(process);
8339                                }
8340                        }
8341                        hasInsertColumns = true;
8342                } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
8343                        TTable table = stmt.getTargetTable();
8344                        Table tableModel = modelFactory.createTable(table);
8345
8346                        inserTables.add(tableModel);
8347                        List<TObjectName> keyMap = new ArrayList<TObjectName>();
8348                        insertTableKeyMap.put(tableModel, keyMap);
8349                        List<TableColumn> tableColumns = new ArrayList<TableColumn>();
8350                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
8351                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8352                                                stmt.getColumnList().getObjectName(i));
8353                                tableColumns.add(tableColumn);
8354                        }
8355                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
8356                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
8357                        }
8358
8359                        // if (stmt.getSubQuery() != null)
8360                        {
8361                                Process process = modelFactory.createProcess(stmt);
8362                                tableModel.addProcess(process);
8363                        }
8364                        hasInsertColumns = true;
8365                } else if (stmt.getOutputClause() != null && stmt.getOutputClause().getSelectItemList().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.getOutputClause().getSelectItemList().size(); i++) {
8374                                TObjectName columnName = stmt.getOutputClause().getSelectItemList().getResultColumn(i).getFieldAttr();
8375                                String column = columnName.toString().toLowerCase();
8376                                if ((column.startsWith("inserted.") || column.startsWith("deleted."))
8377                                                && columnName.getPropertyToken() != null) {
8378                                        column = columnName.getPropertyToken().getAstext();
8379                                        columnName = new TObjectName();
8380                                        columnName.setString(column);
8381                                }
8382                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, columnName);
8383                                tableColumns.add(tableColumn);
8384                        }
8385                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
8386                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
8387                        }
8388
8389                        // if (stmt.getSubQuery() != null)
8390                        {
8391                                Process process = modelFactory.createProcess(stmt);
8392                                tableModel.addProcess(process);
8393                        }
8394                        hasInsertColumns = true;
8395                } else {
8396                        TTable table = stmt.getTargetTable();
8397                        Table tableModel;
8398                        if (table != null) {
8399                                tableModel = modelFactory.createTable(table);
8400                                // if (stmt.getSubQuery() != null)
8401                                {
8402                                        Process process = modelFactory.createProcess(stmt);
8403                                        tableModel.addProcess(process);
8404                                }
8405                                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
8406                                        tableModel.addColumnsFromSQLEnv();
8407                                }
8408                        } else if (stmt.getDirectoryName() != null) {
8409                                tableModel = modelFactory.createTableByName(stmt.getDirectoryName(), true);
8410                                tableModel.setPath(true);
8411                                tableModel.setCreateTable(true);
8412                                TObjectName fileUri = new TObjectName();
8413                                fileUri.setString("uri=" + stmt.getDirectoryName());
8414                                TableColumn tableColumn = modelFactory.createFileUri(tableModel, fileUri);
8415                                // if (stmt.getSubQuery() != null)
8416                                {
8417                                        Process process = modelFactory.createProcess(stmt);
8418                                        tableModel.addProcess(process);
8419                                }
8420                        } else {
8421                                ErrorInfo errorInfo = new ErrorInfo();
8422                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
8423                                errorInfo.setErrorMessage("Can't get target table. InsertSqlStatement is " + stmt.toString());
8424                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
8425                                                stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
8426                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
8427                                                stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
8428                                                ModelBindingManager.getGlobalHash()));
8429                                errorInfo.fillInfo(this);
8430                                errorInfos.add(errorInfo);
8431                                return;
8432                        }
8433                        inserTables.add(tableModel);
8434                        if (table != null
8435                                        && tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null) {
8436                                if (tableModel.getColumns() != null && !tableModel.getColumns().isEmpty()) {
8437                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()),
8438                                                        tableModel.getColumns());
8439                                } else {
8440                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), null);
8441                                }
8442                        }
8443                }
8444
8445                if (stmt.getSubQuery() != null) {
8446                        analyzeSelectStmt(stmt.getSubQuery());
8447                }
8448
8449                Iterator<Table> tableIter = inserTables.iterator();
8450                while (tableIter.hasNext()) {
8451                        Table tableModel = tableIter.next();
8452                        List<TableColumn> tableColumns = tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()));
8453                        List<TObjectName> keyMap = insertTableKeyMap.get(tableModel);
8454                        List<TResultColumn> valueMap = insertTableValueMap.get(tableModel);
8455                        boolean initColumn = (hasInsertColumns && tableColumns != null && !containStarColumn(tableColumns));
8456
8457                        if (stmt.getSubQuery() != null) {
8458
8459                                List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>();
8460                                if (stmt.getSubQuery().getResultColumnList() != null || stmt.getSubQuery().getTransformClause() != null) {
8461                                        subquerys.add(stmt.getSubQuery());
8462                                } else if (stmt.getSubQuery().getValueClause() != null
8463                                                && stmt.getSubQuery().getValueClause().getRows() != null) {
8464                                        for (TResultColumnList resultColumnList : stmt.getSubQuery().getValueClause().getRows()) {
8465                                                for(TResultColumn resultColumn: resultColumnList) {
8466                                                        if(resultColumn.getExpr()!=null && resultColumn.getExpr().getSubQuery()!=null) {
8467                                                                analyzeSelectStmt(resultColumn.getExpr().getSubQuery());
8468                                                                subquerys.add(resultColumn.getExpr().getSubQuery());
8469                                                        }
8470                                                }
8471                                        }
8472                                }
8473
8474                                for(TSelectSqlStatement subquery: subquerys) {
8475                                        if ((tableModel.isCreateTable() && tableModel.getColumns() != null)
8476                                                        || (subquery.getSetOperatorType() == ESetOperatorType.none
8477                                                                        && stmt.getColumnList() != null && stmt.getColumnList().size() > 0)) {
8478
8479                                                ResultSet resultSetModel = null;
8480
8481                                                if (subquery != null) {
8482                                                        resultSetModel = (ResultSet) modelManager.getModel(subquery);
8483                                                }
8484
8485                                                TResultColumnList resultset = subquery.getResultColumnList();
8486                                                if (resultSetModel == null && resultset != null) {
8487                                                        resultSetModel = (ResultSet) modelManager.getModel(resultset);
8488                                                }
8489
8490                                                if (resultSetModel == null) {
8491                                                        ErrorInfo errorInfo = new ErrorInfo();
8492                                                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
8493                                                        errorInfo.setErrorMessage("Can't get resultset model");
8494                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(resultset.getStartToken().lineNo,
8495                                                                        resultset.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
8496                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(resultset.getEndToken().lineNo,
8497                                                                        resultset.getEndToken().columnNo + resultset.getEndToken().getAstext().length(),
8498                                                                        ModelBindingManager.getGlobalHash()));
8499                                                        errorInfos.add(errorInfo);
8500                                                }
8501
8502                                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
8503                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
8504                                                        impactRelation.setEffectType(effectType);
8505                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
8506                                                                        resultSetModel.getRelationRows()));
8507                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
8508                                                                        tableModel.getRelationRows()));
8509                                                }
8510
8511                                                int resultSetSize = resultSetModel.getColumns().size();
8512                                                int j = 0;
8513                                                int starIndex = 0;
8514                                                TObjectNameList items = stmt.getColumnList();
8515                                                List<String> itemNames = new ArrayList<String>();
8516                                                int starColumnCount = 0;
8517                                                for (ResultColumn item : resultSetModel.getColumns()) {
8518                                                        if (item.getName().endsWith("*")) {
8519                                                                starColumnCount += 1;
8520                                                        }
8521                                                }
8522                                                if (items != null) {
8523                                                        for (int i = 0; i < items.size() && j < resultSetSize; i++) {
8524                                                                TObjectName column = items.getObjectName(i);
8525
8526                                                                if (column.getDbObjectType() == EDbObjectType.variable) {
8527                                                                        continue;
8528                                                                }
8529
8530                                                                if (column.getColumnNameOnly().startsWith("@")
8531                                                                                && (option.getVendor() == EDbVendor.dbvmssql
8532                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
8533                                                                        continue;
8534                                                                }
8535
8536                                                                if (column.getColumnNameOnly().startsWith(":")
8537                                                                                && (option.getVendor() == EDbVendor.dbvhana
8538                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
8539                                                                        continue;
8540                                                                }
8541
8542                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
8543                                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
8544                                                                        j++;
8545                                                                } else {
8546                                                                        starIndex++;
8547                                                                        if (resultSetSize - j == items.size() - i) {
8548                                                                                j++;
8549
8550                                                                        }
8551                                                                }
8552                                                                if (column != null) {
8553                                                                        TableColumn tableColumn;
8554                                                                        // if (!initColumn) {
8555                                                                        tableColumn = matchColumn(tableModel.getColumns(), column);
8556                                                                        if (tableColumn == null) {
8557                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8558                                                                                        if (tableModel.getColumns().size() <= i) {
8559                                                                                                continue;
8560                                                                                        }
8561                                                                                        tableColumn = tableModel.getColumns().get(i);
8562                                                                                } else {
8563                                                                                        tableColumn = modelFactory.createTableColumn(tableModel, column, false);
8564                                                                                        if(tableColumn == null) {
8565                                                                                                continue;
8566                                                                                        }
8567                                                                                }
8568                                                                        }
8569//                                                      } else {
8570//                                                              tableColumn = matchColumn(tableColumns, column);
8571//                                                              if (tableColumn == null) {
8572//                                                                      continue;
8573//                                                              }
8574//                                                      }
8575                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8576                                                                        relation.setEffectType(effectType);
8577                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8578                                                                        if (resultColumn.hasStarLinkColumn()
8579                                                                                        && resultColumn.getStarLinkColumnNames().size() > starIndex - 1 && starColumnCount<=1) {
8580                                                                                while (resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8581                                                                                        TObjectName name = resultColumn.getStarLinkColumnName(starIndex - 1);
8582                                                                                        if (itemNames.contains(name.toString())) {
8583                                                                                                starIndex++;
8584                                                                                                continue;
8585                                                                                        }
8586                                                                                        ResultColumn expandStarColumn = modelFactory
8587                                                                                                        .createResultColumn(resultSetModel, name, false);
8588                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8589                                                                                        itemNames.add(resultColumn.getName());
8590                                                                                        break;
8591                                                                                }
8592                                                                        } else {
8593                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8594                                                                                itemNames.add(resultColumn.getName());
8595                                                                        }
8596                                                                        Process process = modelFactory.createProcess(stmt);
8597                                                                        relation.setProcess(process);
8598                                                                }
8599                                                        }
8600                                                } else {
8601                                                        List<TableColumn> columns = tableModel.getColumns();
8602                                                        if (columns.size() == 1 && tableModel.isPath()) {
8603                                                                for(int i=0;i<resultSetSize;i++) {
8604                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
8605                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8606                                                                        relation.setEffectType(effectType);
8607                                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(0)));
8608                                                                        if (resultColumn.hasStarLinkColumn()
8609                                                                                        && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8610                                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(
8611                                                                                                resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
8612                                                                                                false);
8613                                                                                relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8614                                                                        } else {
8615                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8616                                                                        }
8617                                                                        Process process = modelFactory.createProcess(stmt);
8618                                                                        relation.setProcess(process);
8619                                                                }
8620                                                        } else {
8621                                                                boolean fromStruct = false;
8622                                                                for (int i = 0; i < columns.size() && j < resultSetSize; i++) {
8623                                                                        String column = columns.get(i).getName();
8624                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
8625                                                                        if (!resultColumn.getName().contains("*")) {
8626                                                                                if (resultColumn.getName().equals(resultColumn.getRefColumnName())
8627                                                                                                && resultColumn.getColumnObject().toString().endsWith("*")
8628                                                                                                && resultSetSize == 1) {
8629                                                                                        starIndex++;
8630                                                                                        if (resultSetSize - j == columns.size() - i) {
8631                                                                                                j++;
8632
8633                                                                                        }
8634                                                                                }
8635                                                                                else {
8636                                                                                        j++;
8637                                                                                }
8638                                                                        } else {
8639                                                                                starIndex++;
8640                                                                                if (resultSetSize - j == columns.size() - i) {
8641                                                                                        j++;
8642
8643                                                                                }
8644                                                                        }
8645                                                                        if (column != null) {
8646                                                                                TableColumn tableColumn;
8647                                                                                // if (!initColumn) {
8648                                                                                tableColumn = matchColumn(tableModel.getColumns(), columns.get(i));
8649                                                                                if (tableColumn == null) {
8650                                                                                        if (tableModel.isCreateTable()
8651                                                                                                        && !containStarColumn(tableModel.getColumns())) {
8652                                                                                                if (tableModel.getColumns().size() <= i) {
8653                                                                                                        continue;
8654                                                                                                }
8655                                                                                                tableColumn = tableModel.getColumns().get(i);
8656                                                                                        } else {
8657                                                                                                TObjectName columnName = new TObjectName();
8658                                                                                                columnName.setString(column);
8659                                                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName,
8660                                                                                                                false);
8661                                                                                        }
8662                                                                                }
8663                                                                                else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) {
8664                                                                                        j--;
8665                                                                                        fromStruct = true;
8666                                                                                }
8667                                                                                if(fromStruct && !tableColumn.isStruct()) {
8668                                                                                        fromStruct = false;
8669                                                                                        resultColumn = resultSetModel.getColumns().get(j);
8670                                                                                        j++;
8671                                                                                }
8672                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8673                                                                                relation.setEffectType(effectType);
8674                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8675                                                                                if (resultColumn.hasStarLinkColumn()
8676                                                                                                && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8677                                                                                        ResultColumn expandStarColumn = modelFactory.createResultColumn(
8678                                                                                                        resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
8679                                                                                                        false);
8680                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8681                                                                                } else {
8682                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1));
8683                                                                                }
8684                                                                                Process process = modelFactory.createProcess(stmt);
8685                                                                                relation.setProcess(process);
8686                                                                        }
8687                                                                }
8688                                                        }
8689                                                }
8690                                        } else if (!subquery.isCombinedQuery()) {
8691                                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
8692                                                                .getModel(subquery.getResultColumnList() != null ? subquery.getResultColumnList()
8693                                                                                : subquery.getTransformClause());
8694
8695                                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
8696                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
8697                                                        impactRelation.setEffectType(effectType);
8698                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
8699                                                                        resultSetModel.getRelationRows()));
8700                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
8701                                                                        tableModel.getRelationRows()));
8702                                                }
8703
8704                                                List<ResultColumn> columnsSnapshot = new ArrayList<ResultColumn>();
8705                                                columnsSnapshot.addAll(resultSetModel.getColumns());
8706                                                if(resultSetModel.isDetermined() && stmt.getColumnList() == null) {
8707                                                        tableModel.setDetermined(true);
8708                                                }
8709                                                for (int i = 0; i < columnsSnapshot.size(); i++) {
8710                                                        ResultColumn resultColumn = columnsSnapshot.get(i);
8711                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
8712                                                                TableColumn tableColumn;
8713                                                                if (!initColumn) {
8714                                                                        if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8715                                                                                if (tableModel.getColumns().size() <= i) {
8716                                                                                        continue;
8717                                                                                }
8718                                                                                tableColumn = tableModel.getColumns().get(i);
8719                                                                        } else {
8720                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8721                                                                                                (TObjectName) resultColumn.getColumnObject());
8722                                                                        }
8723                                                                        if (containStarColumn(tableColumns)) {
8724                                                                                getStarColumn(tableColumns)
8725                                                                                                .bindStarLinkColumn((TObjectName) resultColumn.getColumnObject());
8726                                                                        }
8727                                                                } else {
8728                                                                        TObjectName matchedColumnName = (TObjectName) resultColumn.getColumnObject();
8729                                                                        tableColumn = matchColumn(tableColumns, matchedColumnName);
8730                                                                        if (tableColumn == null) {
8731                                                                                if (!isEmptyCollection(valueMap)) {
8732                                                                                        int index = indexOfColumn(valueMap, matchedColumnName);
8733                                                                                        if (index != -1) {
8734                                                                                                if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8735                                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(index));
8736                                                                                                } else if (isEmptyCollection(keyMap) && index < tableColumns.size()) {
8737                                                                                                        tableColumn = tableColumns.get(index);
8738                                                                                                } else {
8739                                                                                                        continue;
8740                                                                                                }
8741                                                                                        } else {
8742                                                                                                continue;
8743                                                                                        }
8744                                                                                } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8745                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(i));
8746                                                                                } else if (isEmptyCollection(keyMap) && isEmptyCollection(valueMap)
8747                                                                                                && i < tableColumns.size()) {
8748                                                                                        tableColumn = tableColumns.get(i);
8749                                                                                } else {
8750                                                                                        continue;
8751                                                                                }
8752                                                                        }
8753                                                                }
8754
8755                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8756                                                                relation.setEffectType(effectType);
8757                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8758                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8759                                                                Process process = modelFactory.createProcess(stmt);
8760                                                                relation.setProcess(process);
8761                                                        } else {
8762                                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
8763                                                                if (alias != null && alias.getAliasName() != null) {
8764                                                                        TableColumn tableColumn;
8765                                                                        if (!initColumn) {
8766                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8767                                                                                        if (tableModel.getColumns().size() <= i) {
8768                                                                                                if (tableModel.isPath()) {
8769                                                                                                        tableColumn = tableModel.getColumns().get(0);
8770                                                                                                } else {
8771                                                                                                        continue;
8772                                                                                                }
8773                                                                                        } else {
8774                                                                                                tableColumn = tableModel.getColumns().get(i);
8775                                                                                        }
8776                                                                                } else {
8777                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8778                                                                                                        alias.getAliasName());
8779                                                                                        if (containStarColumn(resultSetModel)) {
8780                                                                                                tableColumn.notBindStarLinkColumn(true);
8781                                                                                        }
8782                                                                                }
8783                                                                                if (containStarColumn(tableColumns)) {
8784                                                                                        getStarColumn(tableColumns).bindStarLinkColumn(alias.getAliasName());
8785                                                                                }
8786                                                                        } else {
8787                                                                                TObjectName matchedColumnName = alias.getAliasName();
8788                                                                                tableColumn = matchColumn(tableColumns, matchedColumnName);
8789                                                                                if (tableColumn == null) {
8790                                                                                        if (!isEmptyCollection(valueMap)) {
8791                                                                                                int index = indexOfColumn(valueMap, matchedColumnName);
8792                                                                                                if (index != -1) {
8793                                                                                                        if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8794                                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(index));
8795                                                                                                        } else if (isEmptyCollection(keyMap)
8796                                                                                                                        && index < tableColumns.size()) {
8797                                                                                                                tableColumn = tableColumns.get(index);
8798                                                                                                        } else {
8799                                                                                                                continue;
8800                                                                                                        }
8801                                                                                                } else {
8802                                                                                                        continue;
8803                                                                                                }
8804                                                                                        } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8805                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(i));
8806                                                                                        } else {
8807                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8808                                                                                                                alias.getAliasName());
8809                                                                                        }
8810                                                                                }
8811
8812                                                                        }
8813
8814                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8815                                                                        relation.setEffectType(effectType);
8816                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8817                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8818                                                                        Process process = modelFactory.createProcess(stmt);
8819                                                                        relation.setProcess(process);
8820
8821                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getFieldAttr() != null) {
8822                                                                        TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
8823                                                                                        .getFieldAttr();
8824
8825                                                                        Object model = modelManager.getModel( resultColumn.getColumnObject());
8826                                                                        
8827                                                                        TableColumn tableColumn;
8828                                                                        if (!initColumn) {
8829                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8830                                                                                        if (fieldAttr.toString().endsWith("*")) {
8831                                                                                                int starIndex = 0;
8832                                                                                                for (TableColumn column : tableModel.getColumns()) {
8833                                                                                                        starIndex++;
8834                                                                                                        DataFlowRelationship relation = modelFactory
8835                                                                                                                        .createDataFlowRelation();
8836                                                                                                        relation.setEffectType(effectType);
8837                                                                                                        relation.setTarget(new TableColumnRelationshipElement(column));
8838                                                                                                        if (resultColumn.getStarLinkColumnList().size() == tableModel
8839                                                                                                                        .getColumns().size()) {
8840                                                                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(
8841                                                                                                                                resultSetModel,
8842                                                                                                                                resultColumn.getStarLinkColumnList().get(starIndex - 1),
8843                                                                                                                                false);
8844                                                                                                                relation.addSource(
8845                                                                                                                                new ResultColumnRelationshipElement(expandStarColumn));
8846                                                                                                        } else {
8847                                                                                                                relation.addSource(
8848                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
8849                                                                                                        }
8850                                                                                                        Process process = modelFactory.createProcess(stmt);
8851                                                                                                        relation.setProcess(process);
8852                                                                                                }
8853                                                                                                continue;
8854                                                                                        }
8855                                                                                        if (tableModel.getColumns().size() <= i) {
8856                                                                                                continue;
8857                                                                                        }
8858                                                                                        tableColumn = tableModel.getColumns().get(i);
8859                                                                                } else {
8860                                                                                        if(model instanceof LinkedHashMap) {
8861                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model;
8862                                                                                                for(String key: resultColumns.keySet()) {
8863                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName());
8864                                                                                                        DataFlowRelationship relation = modelFactory
8865                                                                                                                        .createDataFlowRelation();
8866                                                                                                        relation.setEffectType(effectType);
8867                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8868                                                                                                        relation.addSource(
8869                                                                                                                        new ResultColumnRelationshipElement(resultColumns.get(key)));
8870                                                                                                        Process process = modelFactory.createProcess(stmt);
8871                                                                                                        relation.setProcess(process);
8872                                                                                                }
8873                                                                                                continue;
8874                                                                                        }
8875                                                                                        else {
8876                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel, fieldAttr);
8877                                                                                        }
8878                                                                                }
8879                                                                        } else if (tableModel.isDetermined() && i < tableModel.getColumns().size()) {
8880                                                                                if (!isEmptyCollection(valueMap)) {
8881                                                                                        TObjectName matchedColumnName = fieldAttr;
8882                                                                                        int index = indexOfColumn(valueMap, matchedColumnName);
8883                                                                                        if (index != -1) {
8884                                                                                                if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8885                                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(index));
8886                                                                                                } else if (isEmptyCollection(keyMap)
8887                                                                                                                && index < tableColumns.size()) {
8888                                                                                                        tableColumn = tableColumns.get(index);
8889                                                                                                } else {
8890                                                                                                        continue;
8891                                                                                                }
8892                                                                                        } else {
8893                                                                                                continue;
8894                                                                                        }
8895                                                                                } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8896                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(i));
8897                                                                                } else {
8898                                                                                        tableColumn = tableModel.getColumns().get(i);
8899                                                                                }
8900                                                                        } else {
8901                                                                                TObjectName matchedColumnName = fieldAttr;
8902                                                                                tableColumn = matchColumn(tableColumns, matchedColumnName);
8903                                                                                if (tableColumn == null) {
8904                                                                                        if (!isEmptyCollection(valueMap)) {
8905                                                                                                int index = indexOfColumn(valueMap, matchedColumnName);
8906                                                                                                if (index != -1) {
8907                                                                                                        if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8908                                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(index));
8909                                                                                                        } else if (isEmptyCollection(keyMap)
8910                                                                                                                        && index < tableColumns.size()) {
8911                                                                                                                tableColumn = tableColumns.get(index);
8912                                                                                                        } else {
8913                                                                                                                continue;
8914                                                                                                        }
8915                                                                                                } else {
8916                                                                                                        continue;
8917                                                                                                }
8918                                                                                        } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8919                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(i));
8920                                                                                        } else {
8921                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8922                                                                                                                fieldAttr);
8923                                                                                        }
8924                                                                                }
8925                                                                        }
8926
8927                                                                        if (!"*".equals(getColumnName(tableColumn.getColumnObject()))
8928                                                                                        && "*".equals(getColumnName(fieldAttr))) {
8929                                                                                TObjectName columnObject = fieldAttr;
8930                                                                                TTable sourceTable = columnObject.getSourceTable();
8931                                                                                if (columnObject.getTableToken() != null && sourceTable != null) {
8932                                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
8933                                                                                        for (int j = 0; j < columns.length; j++) {
8934                                                                                                TObjectName columnName = columns[j];
8935                                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
8936                                                                                                        continue;
8937                                                                                                }
8938                                                                                                resultColumn.bindStarLinkColumn(columnName);
8939                                                                                        }
8940                                                                                } else {
8941                                                                                        TTableList tables = stmt.getTables();
8942                                                                                        for (int k = 0; k < tables.size(); k++) {
8943                                                                                                TTable tableElement = tables.getTable(k);
8944                                                                                                TObjectName[] columns = modelManager.getTableColumns(tableElement);
8945                                                                                                for (int j = 0; j < columns.length; j++) {
8946                                                                                                        TObjectName columnName = columns[j];
8947                                                                                                        if (columnName == null || "*".equals(getColumnName(columnName))) {
8948                                                                                                                continue;
8949                                                                                                        }
8950                                                                                                        resultColumn.bindStarLinkColumn(columnName);
8951                                                                                                }
8952                                                                                        }
8953                                                                                }
8954                                                                        }
8955
8956                                                                        if ("*".equals(getColumnName(tableColumn.getColumnObject())) && resultColumn != null
8957                                                                                        && !resultColumn.getStarLinkColumns().isEmpty()) {
8958                                                                                tableColumn.bindStarLinkColumns(resultColumn.getStarLinkColumns());
8959                                                                        }
8960
8961                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8962                                                                        relation.setEffectType(effectType);
8963                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8964                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8965
8966                                                                        if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
8967                                                                                tableColumn.getTable().setStarStmt("insert");
8968                                                                        }
8969
8970                                                                        Process process = modelFactory.createProcess(stmt);
8971                                                                        relation.setProcess(process);
8972                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
8973                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
8974                                                                        if (!initColumn) {
8975                                                                                TableColumn tableColumn;
8976                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8977                                                                                        if (tableModel.getColumns().size() <= i) {
8978                                                                                                continue;
8979                                                                                        }
8980                                                                                        tableColumn = tableModel.getColumns().get(i);
8981                                                                                } else {
8982                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8983                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
8984                                                                                                                        .getConstantOperand(),
8985                                                                                                        i);
8986                                                                                }
8987
8988                                                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
8989                                                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
8990                                                                                        TSQLSchema schema = sqlenv.getSQLSchema(
8991                                                                                                        tableModel.getDatabase() + "." + tableModel.getSchema(), true);
8992                                                                                        if (schema != null) {
8993                                                                                                TSQLTable tempTable = schema.createTable(
8994                                                                                                                DlineageUtil.getSimpleTableName(tableModel.getName()));
8995                                                                                                tempTable.addColumn(tableColumn.getName());
8996                                                                                        }
8997                                                                                }
8998                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8999                                                                                relation.setEffectType(effectType);
9000                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9001                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9002                                                                                Process process = modelFactory.createProcess(stmt);
9003                                                                                relation.setProcess(process);
9004                                                                        } else {
9005                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9006                                                                                relation.setEffectType(effectType);
9007                                                                                relation.setTarget(
9008                                                                                                new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
9009                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9010                                                                                Process process = modelFactory.createProcess(stmt);
9011                                                                                relation.setProcess(process);
9012                                                                        }
9013                                                                } else {
9014                                                                        if (!initColumn) {
9015                                                                                TableColumn tableColumn;
9016                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
9017                                                                                        if (tableModel.getColumns().size() <= i) {
9018                                                                                                continue;
9019                                                                                        }
9020                                                                                        tableColumn = tableModel.getColumns().get(i);
9021                                                                                } else {
9022                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9023                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i);
9024                                                                                }
9025                                                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
9026                                                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
9027                                                                                        TSQLSchema schema = sqlenv.getSQLSchema(
9028                                                                                                        tableModel.getDatabase() + "." + tableModel.getSchema(), true);
9029                                                                                        if (schema != null) {
9030                                                                                                TSQLTable tempTable = schema.createTable(
9031                                                                                                                DlineageUtil.getSimpleTableName(tableModel.getName()));
9032                                                                                                tempTable.addColumn(tableColumn.getName());
9033                                                                                        }
9034                                                                                }
9035                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9036                                                                                relation.setEffectType(effectType);
9037                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9038                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9039                                                                                Process process = modelFactory.createProcess(stmt);
9040                                                                                relation.setProcess(process);
9041                                                                        } else {
9042                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9043                                                                                relation.setEffectType(effectType);
9044                                                                                relation.setTarget(
9045                                                                                                new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
9046                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9047                                                                                Process process = modelFactory.createProcess(stmt);
9048                                                                                relation.setProcess(process);
9049                                                                        }
9050                                                                }
9051                                                        }
9052                                                }
9053                                        } else if (stmt.getSubQuery() != null) {
9054                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
9055                                                if (resultSetModel != null) {
9056
9057                                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
9058                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9059                                                                impactRelation.setEffectType(effectType);
9060                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9061                                                                                resultSetModel.getRelationRows()));
9062                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
9063                                                                                tableModel.getRelationRows()));
9064                                                        }
9065
9066                                                        if(stmt.getColumnList()!=null && stmt.getColumnList().size()>0) {
9067                                                                for(int i=0;i<stmt.getColumnList().size();i++) {
9068                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9069                                                                                        stmt.getColumnList().getObjectName(i));
9070                                                                }
9071                                                                
9072                                                                List<TableColumn> columns = tableModel.getColumns();
9073                                                                int resultSetSize = resultSetModel.getColumns().size();
9074                                                                int starIndex = 0; 
9075                                                                int j = 0;
9076                                                                boolean fromStruct = false;
9077                                                                for (int i = 0; i < columns.size() && j < resultSetSize; i++) {
9078                                                                        String column = columns.get(i).getName();
9079                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
9080                                                                        if (!resultColumn.getName().contains("*")) {
9081                                                                                if (resultColumn.getName().equals(resultColumn.getRefColumnName())
9082                                                                                                && resultColumn.getColumnObject().toString().endsWith("*")
9083                                                                                                && resultSetSize == 1) {
9084                                                                                        starIndex++;
9085                                                                                        if (resultSetSize - j == columns.size() - i) {
9086                                                                                                j++;
9087
9088                                                                                        }
9089                                                                                }
9090                                                                                else {
9091                                                                                        j++;
9092                                                                                }
9093                                                                        } else {
9094                                                                                starIndex++;
9095                                                                                if (resultSetSize - j == columns.size() - i) {
9096                                                                                        j++;
9097
9098                                                                                }
9099                                                                        }
9100                                                                        if (column != null) {
9101                                                                                TableColumn tableColumn;
9102                                                                                // if (!initColumn) {
9103                                                                                tableColumn = matchColumn(tableModel.getColumns(), columns.get(i));
9104                                                                                if (tableColumn == null) {
9105                                                                                        if (tableModel.isCreateTable()
9106                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9107                                                                                                if (tableModel.getColumns().size() <= i) {
9108                                                                                                        continue;
9109                                                                                                }
9110                                                                                                tableColumn = tableModel.getColumns().get(i);
9111                                                                                        } else {
9112                                                                                                TObjectName columnName = new TObjectName();
9113                                                                                                columnName.setString(column);
9114                                                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName,
9115                                                                                                                false);
9116                                                                                        }
9117                                                                                }
9118                                                                                else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) {
9119                                                                                        j--;
9120                                                                                        fromStruct = true;
9121                                                                                }
9122                                                                                if(fromStruct && !tableColumn.isStruct()) {
9123                                                                                        fromStruct = false;
9124                                                                                        resultColumn = resultSetModel.getColumns().get(j);
9125                                                                                        j++;
9126                                                                                }
9127                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9128                                                                                relation.setEffectType(effectType);
9129                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9130                                                                                if (resultColumn.hasStarLinkColumn()
9131                                                                                                && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
9132                                                                                        ResultColumn expandStarColumn = modelFactory.createResultColumn(
9133                                                                                                        resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
9134                                                                                                        false);
9135                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
9136                                                                                } else {
9137                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1));
9138                                                                                }
9139                                                                                Process process = modelFactory.createProcess(stmt);
9140                                                                                relation.setProcess(process);
9141                                                                        }
9142                                                                }
9143                                                        }
9144                                                        else {
9145                                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9146                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9147                                                                        TAliasClause alias = null;
9148                                                                        if(resultColumn.getColumnObject() instanceof TResultColumn) {
9149                                                                                alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
9150                                                                        }
9151                                                                        if (stmt.getColumnList() != null) {
9152                                                                                if (i < stmt.getColumnList().size()) {
9153                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9154                                                                                        relation.setEffectType(effectType);
9155                                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9156                                                                                                        stmt.getColumnList().getObjectName(i));
9157                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9158                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9159                                                                                        Process process = modelFactory.createProcess(stmt);
9160                                                                                        relation.setProcess(process);
9161                                                                                }
9162                                                                        } else {
9163                                                                                if (alias != null && alias.getAliasName() != null) {
9164                                                                                        TableColumn tableColumn;
9165                                                                                        if (!initColumn) {
9166                                                                                                if (tableModel.isCreateTable()
9167                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9168                                                                                                        if (tableModel.getColumns().size() <= i) {
9169                                                                                                                continue;
9170                                                                                                        }
9171                                                                                                        tableColumn = tableModel.getColumns().get(i);
9172                                                                                                } else {
9173                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9174                                                                                                                        alias.getAliasName());
9175                                                                                                }
9176                                                                                        } else {
9177                                                                                                tableColumn = matchColumn(tableColumns, alias.getAliasName());
9178                                                                                                if (tableColumn == null) {
9179                                                                                                        continue;
9180                                                                                                }
9181                                                                                        }
9182        
9183                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9184                                                                                        relation.setEffectType(effectType);
9185                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9186                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9187                                                                                        Process process = modelFactory.createProcess(stmt);
9188                                                                                        relation.setProcess(process);
9189                                                                                } else if (resultColumn.getColumnObject() instanceof TObjectName 
9190                                                                                                || ( resultColumn.getColumnObject() instanceof TResultColumn && ((TResultColumn) resultColumn.getColumnObject())
9191                                                                                                .getFieldAttr() != null)) {
9192                                                                                        TObjectName fieldAttr = null;
9193                                                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
9194                                                                                                fieldAttr = (TObjectName)resultColumn.getColumnObject();
9195                                                                                        }
9196                                                                                        else if (resultColumn.getColumnObject() instanceof TResultColumn) {
9197                                                                                                fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
9198                                                                                                                .getFieldAttr();
9199                                                                                        }
9200                                
9201                                                                                        TableColumn tableColumn;
9202                                                                                        if (!initColumn) {
9203                                                                                                if (tableModel.isCreateTable()
9204                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9205                                                                                                        if (tableModel.getColumns().size() <= i) {
9206                                                                                                                continue;
9207                                                                                                        }
9208                                                                                                        tableColumn = tableModel.getColumns().get(i);
9209                                                                                                } else {
9210                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9211                                                                                                                        fieldAttr);
9212                                                                                                }
9213                                                                                        } else {
9214                                                                                                tableColumn = matchColumn(tableColumns, fieldAttr);
9215                                                                                                if (tableColumn == null) {
9216                                                                                                        continue;
9217                                                                                                }
9218                                                                                        }
9219        
9220                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9221                                                                                        relation.setEffectType(effectType);
9222                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9223                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9224                                                                                        Process process = modelFactory.createProcess(stmt);
9225                                                                                        relation.setProcess(process);
9226                                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9227                                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
9228                                                                                        if (!initColumn) {
9229                                                                                                TableColumn tableColumn;
9230                                                                                                if (tableModel.isCreateTable()
9231                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9232                                                                                                        if (tableModel.getColumns().size() <= i) {
9233                                                                                                                continue;
9234                                                                                                        }
9235                                                                                                        tableColumn = tableModel.getColumns().get(i);
9236                                                                                                } else {
9237                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9238                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9239                                                                                                                                        .getConstantOperand(),
9240                                                                                                                        i);
9241                                                                                                }
9242                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9243                                                                                                relation.setEffectType(effectType);
9244                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9245                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9246                                                                                                Process process = modelFactory.createProcess(stmt);
9247                                                                                                relation.setProcess(process);
9248                                                                                        }
9249                                                                                } else {
9250                                                                                        if (!initColumn) {
9251                                                                                                TableColumn tableColumn;
9252                                                                                                if (tableModel.isCreateTable()
9253                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9254                                                                                                        if (tableModel.getColumns().size() <= i) {
9255                                                                                                                continue;
9256                                                                                                        }
9257                                                                                                        tableColumn = tableModel.getColumns().get(i);
9258                                                                                                } else {
9259                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9260                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i);
9261                                                                                                }
9262                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9263                                                                                                relation.setEffectType(effectType);
9264                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9265                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9266                                                                                                Process process = modelFactory.createProcess(stmt);
9267                                                                                                relation.setProcess(process);
9268                                                                                        }
9269                                                                                }
9270                                                                        }
9271                                                                }
9272                                                        }
9273                                                }
9274                                        }
9275                                }
9276                        } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
9277                                TObjectNameList items = stmt.getColumnList();
9278                                TMultiTargetList values = stmt.getValues();
9279                                if (values != null) {
9280                                        for (int k = 0; values != null && k < values.size(); k++) {
9281                                                int j = 0;
9282                                                for (int i = 0; i < items.size(); i++) {
9283                                                        TObjectName column = items.getObjectName(i);
9284                                                        TableColumn tableColumn;
9285                                                        if (!initColumn) {
9286                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
9287                                                                        if (tableModel.getColumns().size() <= i) {
9288                                                                                continue;
9289                                                                        }
9290                                                                        tableColumn = tableModel.getColumns().get(i);
9291                                                                } else {
9292                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, column);
9293                                                                }
9294                                                        } else {
9295                                                                tableColumn = matchColumn(tableColumns, column);
9296                                                                if (tableColumn == null) {
9297                                                                        continue;
9298                                                                }
9299                                                        }
9300                                                        TResultColumn columnObject = values.getMultiTarget(k).getColumnList().getResultColumn(j);
9301                                                        if (columnObject == null) {
9302                                                                continue;
9303                                                        }
9304                                                        TExpression valueExpr = columnObject.getExpr();
9305                                                        columnsInExpr visitor = new columnsInExpr();
9306                                                        valueExpr.inOrderTraverse(visitor);
9307                                                        List<TObjectName> objectNames = visitor.getObjectNames();
9308                                                        List<TParseTreeNode> constants = visitor.getConstants();
9309                                                        List<TParseTreeNode> functions = visitor.getFunctions();
9310                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9311
9312                                                        Process process = modelFactory.createProcess(stmt);
9313                                                        
9314                                                        
9315                                                        
9316                                                        if (functions != null && !functions.isEmpty()) {
9317                                                                analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process);
9318                                                        }
9319
9320                                                        if (subquerys != null && !subquerys.isEmpty()) {
9321                                                                analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process);
9322                                                        }
9323                                                        if (objectNames != null && !objectNames.isEmpty()) {
9324                                                                analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions,
9325                                                                                process, i);
9326                                                        }
9327                                                        //insert into values generate too many constant relations, ignore constant relations.
9328                                                        if (constants != null && !constants.isEmpty()) {
9329                                                                if (!option.isIgnoreInsertIntoValues() || stmt.getParentStmt() != null) {
9330                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, effectType,
9331                                                                                        functions, process);
9332                                                                }
9333                                                        }
9334                                                        j++;
9335                                                }
9336                                        }
9337                                } else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) {
9338                                        analyzeCustomSqlStmt(stmt.getExecuteStmt());
9339                                        Procedure procedure = modelManager.getProcedureByName(DlineageUtil
9340                                                        .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString()));
9341                                        if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) {
9342                                                TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure
9343                                                                .getProcedureObject();
9344                                                List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt);
9345                                                if (stmtItems != null) {
9346                                                        for(TSelectSqlStatement stmtItem: stmtItems) {
9347                                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem);
9348                                                                if (resultSetModel != null) {
9349                                                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9350                                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9351                                                                                Transform transform = new Transform();
9352                                                                                transform.setType(Transform.FUNCTION);
9353                                                                                transform.setCode(stmt.getExecuteStmt().getModuleName());
9354                                                                                resultColumn.setTransform(transform);
9355                                                                                
9356                                                                                if (stmt.getColumnList() != null) {
9357                                                                                        if (i < stmt.getColumnList().size()) {
9358                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9359                                                                                                relation.setEffectType(effectType);
9360                                                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9361                                                                                                                stmt.getColumnList().getObjectName(i));                                                                                         
9362                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9363                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9364                                                                                                Process process = modelFactory.createProcess(stmt);
9365                                                                                                relation.setProcess(process);                                   
9366                                                                                        }
9367                                                                                } else {
9368                                                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
9369                                                                                                TObjectName fieldAttr = ((TObjectName) resultColumn.getColumnObject());
9370                                                                                                TableColumn tableColumn;
9371                                                                                                if (!initColumn) {
9372                                                                                                        if (tableModel.isCreateTable()
9373                                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9374                                                                                                                if (tableModel.getColumns().size() <= i) {
9375                                                                                                                        continue;
9376                                                                                                                }
9377                                                                                                                tableColumn = tableModel.getColumns().get(i);
9378                                                                                                        } else {
9379                                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9380                                                                                                                                fieldAttr);
9381                                                                                                        }
9382                                                                                                } else {
9383                                                                                                        tableColumn = matchColumn(tableColumns, fieldAttr);
9384                                                                                                        if (tableColumn == null) {
9385                                                                                                                continue;
9386                                                                                                        }
9387                                                                                                }
9388        
9389                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9390                                                                                                relation.setEffectType(effectType);
9391                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9392                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9393                                                                                                Process process = modelFactory.createProcess(stmt);
9394                                                                                                relation.setProcess(process);
9395
9396                                                                                                
9397                                                                                        } else {
9398                                                                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject())
9399                                                                                                                .getAliasClause();
9400                                                                                                if (alias != null && alias.getAliasName() != null) {
9401                                                                                                        TableColumn tableColumn;
9402                                                                                                        if (!initColumn) {
9403                                                                                                                if (tableModel.isCreateTable()
9404                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9405                                                                                                                        if (tableModel.getColumns().size() <= i) {
9406                                                                                                                                continue;
9407                                                                                                                        }
9408                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9409                                                                                                                } else {
9410                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9411                                                                                                                                        alias.getAliasName());
9412                                                                                                                }
9413                                                                                                        } else {
9414                                                                                                                tableColumn = matchColumn(tableColumns, alias.getAliasName());
9415                                                                                                                if (tableColumn == null) {
9416                                                                                                                        continue;
9417                                                                                                                }
9418                                                                                                        }
9419                                                                                                        
9420                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9421                                                                                                        relation.setEffectType(effectType);
9422                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9423                                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9424                                                                                                        Process process = modelFactory.createProcess(stmt);
9425                                                                                                        relation.setProcess(process);
9426                                                                                                } else if (((TResultColumn) resultColumn.getColumnObject())
9427                                                                                                                .getFieldAttr() != null) {
9428                                                                                                        TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
9429                                                                                                                        .getFieldAttr();
9430                                                                                                        TableColumn tableColumn;
9431                                                                                                        if (!initColumn) {
9432                                                                                                                if (tableModel.isCreateTable()
9433                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9434                                                                                                                        if (tableModel.getColumns().size() <= i) {
9435                                                                                                                                continue;
9436                                                                                                                        }
9437                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9438                                                                                                                } else {
9439                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9440                                                                                                                                        fieldAttr);
9441                                                                                                                }
9442                                                                                                        } else {
9443                                                                                                                tableColumn = matchColumn(tableColumns, fieldAttr);
9444                                                                                                                if (tableColumn == null) {
9445                                                                                                                        continue;
9446                                                                                                                }
9447                                                                                                        }
9448                                                                                                        
9449                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9450                                                                                                        relation.setEffectType(effectType);
9451                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9452                                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9453                                                                                                        Process process = modelFactory.createProcess(stmt);
9454                                                                                                        relation.setProcess(process);                                                                                                   
9455                                                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9456                                                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
9457                                                                                                        if (!initColumn) {
9458                                                                                                                TableColumn tableColumn;
9459                                                                                                                if (tableModel.isCreateTable()
9460                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9461                                                                                                                        if (tableModel.getColumns().size() <= i) {
9462                                                                                                                                continue;
9463                                                                                                                        }
9464                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9465                                                                                                                } else {
9466                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9467                                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9468                                                                                                                                                        .getConstantOperand(),
9469                                                                                                                                        i);
9470                                                                                                                }
9471                                                                                                                
9472                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9473                                                                                                                relation.setEffectType(effectType);
9474                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9475                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9476                                                                                                                Process process = modelFactory.createProcess(stmt);
9477                                                                                                                relation.setProcess(process);
9478                                                                                                        }
9479                                                                                                } else {
9480                                                                                                        if (!initColumn) {
9481                                                                                                                TableColumn tableColumn;
9482                                                                                                                if (tableModel.isCreateTable()
9483                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9484                                                                                                                        if (tableModel.getColumns().size() <= i) {
9485                                                                                                                                continue;
9486                                                                                                                        }
9487                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9488                                                                                                                } else {
9489                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9490                                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(),
9491                                                                                                                                        i);
9492                                                                                                                }
9493                                                                                                                
9494                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9495                                                                                                                relation.setEffectType(effectType);
9496                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9497                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9498                                                                                                                Process process = modelFactory.createProcess(stmt);
9499                                                                                                                relation.setProcess(process);
9500                                                                                                        }
9501                                                                                                }
9502                                                                                        }
9503                                                                                }
9504                                                                        }
9505                                                                }
9506                                                        }
9507                                                }
9508                                        }
9509                                        else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) {
9510                                                TObjectName functionName = new TObjectName();
9511                                                functionName.setString(procedure.getName());
9512                                                Function function = (Function)createFunction(functionName);
9513                                                if (stmt.getColumnList() != null) {
9514                                                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
9515                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9516                                                                relation.setEffectType(effectType);
9517                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9518                                                                                stmt.getColumnList().getObjectName(i));
9519                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9520                                                                relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
9521                                                                Process process = modelFactory.createProcess(stmt);
9522                                                                relation.setProcess(process);
9523                                                        }
9524                                                }
9525                                        }
9526                                }
9527                        } else if (stmt.getValues() != null && stmt.getValues().size() > 0 && tableModel.isCreateTable()) {
9528                                for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) {
9529                                        TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList();
9530                                        boolean allConstant = true;
9531                                        Process process = modelFactory.createProcess(stmt);
9532                                        for (int x = 0; x < columns.size(); x++) {
9533                                                TableColumn tableColumn = tableModel.getColumns().get(x);
9534                                                TResultColumn columnObject = columns.getResultColumn(x);
9535                                                if (columnObject == null) {
9536                                                        continue;
9537                                                }
9538                                                TExpression valueExpr = columnObject.getExpr();
9539                                                columnsInExpr visitor = new columnsInExpr();
9540                                                valueExpr.inOrderTraverse(visitor);
9541                                                List<TObjectName> objectNames = visitor.getObjectNames();
9542                                                List<TParseTreeNode> constants = visitor.getConstants();
9543                                                List<TParseTreeNode> functions = visitor.getFunctions();
9544                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9545
9546                                                if (functions != null && !functions.isEmpty()) {
9547                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process);
9548                                                        allConstant = false;
9549                                                }
9550
9551                                                if (subquerys != null && !subquerys.isEmpty()) {
9552                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process);
9553                                                        allConstant = false;
9554                                                }
9555                                                if (objectNames != null && !objectNames.isEmpty()) {
9556                                                        analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions,
9557                                                                        process);
9558                                                        allConstant = false;
9559                                                }
9560                                                //insert into values generate too many constant relations, ignore constant relations.
9561                                                if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) {
9562                                                        analyzeConstantDataFlowRelation(tableColumn, constants, effectType, functions,
9563                                                                        process);
9564                                                        allConstant = false;
9565                                                }
9566                                        }
9567                                        
9568                                        if(allConstant) {
9569                                                modelManager.unbindProcessModel(stmt);
9570                                                tableModel.removeProcess(process);
9571                                        }
9572                                }
9573                        } else if (stmt.getRecordName() != null) {
9574                                String procedureName = DlineageUtil.getProcedureParentName(stmt);
9575                                String variableString = stmt.getRecordName().toString();
9576                                if (variableString.startsWith(":")) {
9577                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
9578                                }
9579                                if (!SQLUtil.isEmpty(procedureName)) {
9580                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
9581                                }
9582                                
9583                                Table recordTable = modelManager
9584                                                .getTableByName(DlineageUtil.getTableFullName(variableString));
9585                                if (recordTable != null) {
9586                                        for (int i = 0; i < recordTable.getColumns().size(); i++) {
9587                                                TableColumn sourceTableColumn = recordTable.getColumns().get(i);
9588                                                TableColumn targetTableColumn = modelFactory.createTableColumn(tableModel,
9589                                                                sourceTableColumn.getColumnObject(), false);
9590                                                if (targetTableColumn != null) {
9591                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9592                                                        relation.setEffectType(effectType);
9593                                                        relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
9594                                                        relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
9595                                                        Process process = modelFactory.createProcess(stmt);
9596                                                        relation.setProcess(process);
9597                                                } else if (sourceTableColumn.getName().endsWith("*") && tableModel.isCreateTable()) {
9598                                                        for (TableColumn column : tableModel.getColumns()) {
9599                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9600                                                                relation.setEffectType(effectType);
9601                                                                relation.setTarget(new TableColumnRelationshipElement(column));
9602                                                                relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
9603                                                                Process process = modelFactory.createProcess(stmt);
9604                                                                relation.setProcess(process);
9605                                                        }
9606                                                }
9607                                        }
9608                                }
9609                        } else if (stmt.getInsertSource() == EInsertSource.values_function && stmt.getFunctionCall() != null) {
9610                                Table cursor = modelManager.getTableByName(
9611                                                DlineageUtil.getTableFullName(stmt.getFunctionCall().getFunctionName().toString()));
9612                                if (cursor != null) {
9613                                        TObjectName starColumn = new TObjectName();
9614                                        starColumn.setString("*");
9615                                        TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
9616                                        insertColumn.setShowStar(false);
9617                                        insertColumn.setExpandStar(true);
9618                                        for (int j = 0; j < cursor.getColumns().size(); j++) {
9619                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
9620                                                dataflowRelation.setEffectType(effectType);
9621                                                dataflowRelation.addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j)));
9622                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(insertColumn));
9623                                                Process process = modelFactory.createProcess(stmt);
9624                                                dataflowRelation.setProcess(process);
9625                                        }
9626                                }
9627
9628                        } else if (stmt.getInsertSource() == EInsertSource.values && stmt.getValues() != null) {
9629                                TObjectName starColumn = new TObjectName();
9630                                starColumn.setString("*");
9631                                TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
9632                                insertColumn.setShowStar(false);
9633                                insertColumn.setExpandStar(true);
9634                                for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) {
9635                                        TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList();
9636                                        for (int x = 0; x < columns.size(); x++) {
9637                                                TResultColumn columnObject = columns.getResultColumn(x);
9638                                                if (columnObject == null) {
9639                                                        continue;
9640                                                }
9641                                                TExpression valueExpr = columnObject.getExpr();
9642                                                columnsInExpr visitor = new columnsInExpr();
9643                                                valueExpr.inOrderTraverse(visitor);
9644                                                List<TObjectName> objectNames = visitor.getObjectNames();
9645                                                List<TParseTreeNode> constants = visitor.getConstants();
9646                                                List<TParseTreeNode> functions = visitor.getFunctions();
9647                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9648
9649                                                Process process = modelFactory.createProcess(stmt);
9650                                                if (functions != null && !functions.isEmpty()) {
9651                                                        analyzeFunctionDataFlowRelation(insertColumn, functions, effectType, process);
9652                                                }
9653
9654                                                if (subquerys != null && !subquerys.isEmpty()) {
9655                                                        analyzeSubqueryDataFlowRelation(insertColumn, subquerys, effectType, process);
9656                                                }
9657                                                if (objectNames != null && !objectNames.isEmpty()) {
9658                                                        analyzeDataFlowRelation(insertColumn, objectNames, null, effectType, functions,
9659                                                                        process);
9660                                                }
9661                                                //insert into values generate too many constant relations, ignore constant relations.
9662                                                if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) {
9663                                                        analyzeConstantDataFlowRelation(insertColumn, constants, effectType, functions,
9664                                                                        process);
9665                                                }
9666                                        }
9667                                }
9668                        }else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) {
9669                                analyzeCustomSqlStmt(stmt.getExecuteStmt());
9670                                Procedure procedure = modelManager.getProcedureByName(DlineageUtil
9671                                                .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString()));
9672                                if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) {
9673                                        TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure
9674                                                        .getProcedureObject();
9675                                        List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt);
9676                                        if (stmtItems != null) {
9677                                                for(TSelectSqlStatement stmtItem: stmtItems) {
9678                                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem);
9679                                                        if (resultSetModel != null) {
9680                                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9681                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9682                                                                        
9683                                                                        Transform transform = new Transform();
9684                                                                        transform.setType(Transform.FUNCTION);
9685                                                                        transform.setCode(stmt.getExecuteStmt().getModuleName());
9686                                                                        resultColumn.setTransform(transform);
9687                                                                        
9688                                                                        TAliasClause alias = null;
9689
9690                                                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
9691                                                                                alias = ((TResultColumn) resultColumn.getColumnObject())
9692                                                                                                .getAliasClause();
9693                                                                        }
9694                                                                        
9695                                                                        if (alias != null && alias.getAliasName() != null) {
9696                                                                                TableColumn tableColumn;
9697                                                                                if (!initColumn) {
9698                                                                                        if (tableModel.isCreateTable()
9699                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9700                                                                                                if(resultColumn.getName().endsWith("*")) {
9701                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9702                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9703                                                                                                                relation.setEffectType(effectType);
9704                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9705                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9706                                                                                                                Process process = modelFactory.createProcess(stmt);
9707                                                                                                                relation.setProcess(process);
9708                                                                                                        }
9709                                                                                                        continue;
9710                                                                                                }
9711                                                                                                else {
9712                                                                                                        if (tableModel.getColumns().size() <= i) {
9713                                                                                                                continue;
9714                                                                                                        }
9715                                                                                                        tableColumn = tableModel.getColumns().get(i);
9716                                                                                                }
9717                                                                                        } else {
9718                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9719                                                                                                                alias.getAliasName());
9720                                                                                        }
9721                                                                                } else {
9722                                                                                        tableColumn = matchColumn(tableColumns, alias.getAliasName());
9723                                                                                        if (tableColumn == null) {
9724                                                                                                continue;
9725                                                                                        }
9726                                                                                }
9727                                        
9728                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9729                                                                                relation.setEffectType(effectType);
9730                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9731                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9732                                                                                Process process = modelFactory.createProcess(stmt);
9733                                                                                relation.setProcess(process);
9734                                                                        } else if (((TResultColumn) resultColumn.getColumnObject())
9735                                                                                        .getFieldAttr() != null) {
9736                                                                                TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
9737                                                                                                .getFieldAttr();
9738                                                                                TableColumn tableColumn;
9739                                                                                if (!initColumn) {
9740                                                                                        if (tableModel.isCreateTable()
9741                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9742                                                                                                if(resultColumn.getName().endsWith("*")) {
9743                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9744                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9745                                                                                                                relation.setEffectType(effectType);
9746                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9747                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9748                                                                                                                Process process = modelFactory.createProcess(stmt);
9749                                                                                                                relation.setProcess(process);
9750                                                                                                        }
9751                                                                                                        continue;
9752                                                                                                }
9753                                                                                                else {
9754                                                                                                        if (tableModel.getColumns().size() <= i) {
9755                                                                                                                continue;
9756                                                                                                        }
9757                                                                                                        tableColumn = tableModel.getColumns().get(i);
9758                                                                                                }
9759                                                                                        } else {
9760                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9761                                                                                                                fieldAttr);
9762                                                                                        }
9763                                                                                } else {
9764                                                                                        tableColumn = matchColumn(tableColumns, fieldAttr);
9765                                                                                        if (tableColumn == null) {
9766                                                                                                continue;
9767                                                                                        }
9768                                                                                }
9769                                                                                
9770                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9771                                                                                relation.setEffectType(effectType);
9772                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9773                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9774                                                                                Process process = modelFactory.createProcess(stmt);
9775                                                                                relation.setProcess(process);
9776                                                                        } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9777                                                                                        .getExpressionType() == EExpressionType.simple_constant_t) {
9778                                                                                if (!initColumn) {
9779                                                                                        TableColumn tableColumn;
9780                                                                                        if (tableModel.isCreateTable()
9781                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9782                                                                                                if(resultColumn.getName().endsWith("*")) {
9783                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9784                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9785                                                                                                                relation.setEffectType(effectType);
9786                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9787                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9788                                                                                                                Process process = modelFactory.createProcess(stmt);
9789                                                                                                                relation.setProcess(process);
9790                                                                                                        }
9791                                                                                                        continue;
9792                                                                                                }
9793                                                                                                else {
9794                                                                                                        if (tableModel.getColumns().size() <= i) {
9795                                                                                                                continue;
9796                                                                                                        }
9797                                                                                                        tableColumn = tableModel.getColumns().get(i);
9798                                                                                                }
9799                                                                                        } else {
9800                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9801                                                                                                                ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9802                                                                                                                                .getConstantOperand(),
9803                                                                                                                i);
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                                                                                }
9813                                                                        } else {
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                                                                                                                i);
9839                                                                                        }
9840                                                                                        
9841                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9842                                                                                        relation.setEffectType(effectType);
9843                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9844                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9845                                                                                        Process process = modelFactory.createProcess(stmt);
9846                                                                                        relation.setProcess(process);
9847                                                                                }
9848                                                                        }
9849                                                                }
9850                                                        }
9851                                                }
9852                                        }
9853                                }
9854                                else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) {
9855                                        TObjectName functionName = new TObjectName();
9856                                        functionName.setString(procedure.getName());
9857                                        Function function = (Function)createFunction(functionName);
9858                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9859                                        relation.setEffectType(effectType);
9860                                        TObjectName starColumn = new TObjectName();
9861                                        starColumn.setString("*");
9862                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9863                                                        starColumn);
9864                                        tableColumn.setExpandStar(false);
9865                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9866                                        relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
9867                                        Process process = modelFactory.createProcess(stmt);
9868                                        relation.setProcess(process);
9869                                }
9870                        }
9871                }
9872                
9873                if(stmt.getOnDuplicateKeyUpdate()!=null) {
9874                        TTable table = stmt.getTargetTable();
9875                        Table tableModel = modelFactory.createTable(table);
9876                        for(TResultColumn column: stmt.getOnDuplicateKeyUpdate()) {
9877                                if(column.getExpr()==null || column.getExpr().getExpressionType() != EExpressionType.assignment_t) {
9878                                        continue;
9879                                }
9880                                TExpression left = column.getExpr().getLeftOperand();
9881                                TExpression right = column.getExpr().getRightOperand();
9882                                TObjectName columnObject = left.getObjectOperand();
9883                                if (columnObject != null) {
9884                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false);
9885                                        if (tableColumn != null) {
9886                                                columnsInExpr visitor = new columnsInExpr();
9887                                                right.inOrderTraverse(visitor);
9888                                                List<TObjectName> objectNames = visitor.getObjectNames();
9889                                                List<TParseTreeNode> functions = visitor.getFunctions();
9890                                                List<TParseTreeNode> constants = visitor.getConstants();
9891                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9892
9893                                                if (functions != null && !functions.isEmpty()) {
9894                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.update);
9895                                                }
9896                                                if (subquerys != null && !subquerys.isEmpty()) {
9897                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.update);
9898                                                }
9899                                                if (objectNames != null && !objectNames.isEmpty()) {
9900                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.update, functions);
9901                                                }
9902                                                if (constants != null && !constants.isEmpty()) {
9903                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.update, functions);
9904                                                }
9905                                        }
9906                                }
9907                        }
9908                }
9909
9910                if (!expressions.isEmpty() && stmt.getSubQuery() != null) {
9911                        analyzeInsertImpactRelation(stmt.getSubQuery(), tableColumnMap, expressions, effectType);
9912                }
9913        }
9914
9915        private List<TSelectSqlStatement> getLastSelectStmt(TStoredProcedureSqlStatement procedureStmt) {
9916                List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>();
9917                if (procedureStmt.getBodyStatements().size() > 0) {
9918                        for (int j = procedureStmt.getBodyStatements().size() - 1; j >= 0; j--) {
9919                                TCustomSqlStatement stmtItem = procedureStmt.getBodyStatements().get(j);
9920                                if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) {
9921                                        if (stmtItem.getStatements() != null) {
9922                                                List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9923                                                if (item != null && !item.isEmpty()) {
9924                                                        stmts.addAll(item);
9925                                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9926                                                                break;
9927                                                        }
9928                                                }
9929                                        }
9930                                        break;
9931                                }
9932                                if (stmtItem instanceof TSelectSqlStatement) {
9933                                        stmts.add((TSelectSqlStatement) stmtItem);
9934                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9935                                                break;
9936                                        }
9937                                } else if (stmtItem.getStatements() != null) {
9938                                        List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9939                                        if (item != null && !item.isEmpty()) {
9940                                                stmts.addAll(item);
9941                                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9942                                                        break;
9943                                                }
9944                                        }
9945                                }
9946                        }
9947                }
9948                return stmts;
9949        }
9950
9951        private List<TSelectSqlStatement> getLastSelectStmt(TCustomSqlStatement stmt) {
9952                List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>();
9953                for (int j = stmt.getStatements().size() - 1; j >= 0; j--) {
9954                        TCustomSqlStatement stmtItem = stmt.getStatements().get(j);
9955                        if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) {
9956                                if (stmtItem.getStatements() != null) {
9957                                        List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9958                                        if (item != null && !item.isEmpty()) {
9959                                                stmts.addAll(item);
9960                                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9961                                                        break;
9962                                                }
9963                                        }
9964                                }
9965                                break;
9966                        }
9967                        if (stmtItem instanceof TSelectSqlStatement) {
9968                                stmts.add((TSelectSqlStatement) stmtItem);
9969                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9970                                        break;
9971                                }
9972                        } else if (stmtItem.getStatements() != null) {
9973                                List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9974                                if (item != null && !item.isEmpty()) {
9975                                        stmts.addAll(item);
9976                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9977                                                break;
9978                                        }
9979                                }
9980                        }
9981                }
9982                return stmts;
9983        }
9984
9985        private TableColumn getStarColumn(List<TableColumn> columns) {
9986                for (TableColumn column : columns) {
9987                        if (column.getName().endsWith("*")) {
9988                                return column;
9989                        }
9990                }
9991                return null;
9992        }
9993
9994        private boolean containStarColumn(List<TableColumn> columns) {
9995                if (columns == null)
9996                        return false;
9997                for (TableColumn column : columns) {
9998                        if (column.getName().endsWith("*")) {
9999                                return true;
10000                        }
10001                }
10002                return false;
10003        }
10004
10005        private boolean containStarColumn(ResultSet resultSet) {
10006                if (resultSet == null || resultSet.getColumns() == null)
10007                        return false;
10008                for (ResultColumn column : resultSet.getColumns()) {
10009                        if (column.getName().endsWith("*")) {
10010                                return true;
10011                        }
10012                }
10013                return false;
10014        }
10015
10016        private int indexOfColumn(List<TResultColumn> columns, TObjectName objectName) {
10017                for (int i = 0; i < columns.size(); i++) {
10018                        if (columns.get(i).toString().trim().equalsIgnoreCase(objectName.toString().trim())) {
10019                                return i;
10020                        }
10021                }
10022                return -1;
10023        }
10024
10025        private boolean isEmptyCollection(Collection<?> keyMap) {
10026                return keyMap == null || keyMap.isEmpty();
10027        }
10028
10029        private void analyzeInsertImpactRelation(TSelectSqlStatement stmt, Map<String, List<TableColumn>> insertMap,
10030                        List<TExpression> expressions, EffectType effectType) {
10031                List<TObjectName> objectNames = new ArrayList<TObjectName>();
10032                for (int i = 0; i < expressions.size(); i++) {
10033                        TExpression condition = expressions.get(i);
10034                        columnsInExpr visitor = new columnsInExpr();
10035                        condition.inOrderTraverse(visitor);
10036                        objectNames.addAll(visitor.getObjectNames());
10037                }
10038
10039                Iterator<String> iter = insertMap.keySet().iterator();
10040                while (iter.hasNext()) {
10041                        String table = iter.next();
10042                        List<TableColumn> tableColumns = insertMap.get(table);
10043                        for (int i = 0; i < tableColumns.size(); i++) {
10044
10045                                TableColumn column = tableColumns.get(i);
10046                                ImpactRelationship relation = modelFactory.createImpactRelation();
10047                                relation.setEffectType(effectType);
10048                                relation.setTarget(new TableColumnRelationshipElement(column));
10049
10050                                for (int j = 0; j < objectNames.size(); j++) {
10051                                        TObjectName columnName = objectNames.get(j);
10052                                        Object model = modelManager.getModel(stmt);
10053                                        if (model instanceof SelectResultSet) {
10054                                                SelectResultSet queryTable = (SelectResultSet) model;
10055                                                List<ResultColumn> columns = queryTable.getColumns();
10056                                                for (int k = 0; k < columns.size(); k++) {
10057                                                        ResultColumn resultColumn = columns.get(k);
10058                                                        if (resultColumn.getAlias() != null
10059                                                                        && columnName.toString().equalsIgnoreCase(resultColumn.getAlias())) {
10060                                                                relation.addSource(
10061                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
10062                                                        } else if (resultColumn.getName() != null
10063                                                                        && columnName.toString().equalsIgnoreCase(resultColumn.getName())) {
10064                                                                relation.addSource(
10065                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
10066                                                        }
10067                                                }
10068                                        }
10069                                }
10070                        }
10071                }
10072        }
10073
10074        private void analyzeUpdateStmt(TUpdateSqlStatement stmt) {
10075                if (stmt.getResultColumnList() == null)
10076                        return;
10077
10078                TTable table = stmt.getTargetTable();
10079                while (table.getCTE() != null || table.getSubquery() != null || (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null)) {
10080                        if (table.getCTE() != null) {
10081                                table = table.getCTE().getSubquery().getTables().getTable(0);
10082                        } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) {
10083                                table = table.getLinkTable().getSubquery().getTables().getTable(0);
10084                        } else if (table.getSubquery() != null) {
10085                                table = table.getSubquery().getTables().getTable(0);
10086                        }
10087                }
10088                Table tableModel = modelFactory.createTable(table);
10089                Process process = modelFactory.createProcess(stmt);
10090                tableModel.addProcess(process);
10091
10092                for (int i = 0; i < stmt.tables.size(); i++) {
10093                        TTable tableElement = stmt.tables.getTable(i);
10094                        if (tableElement.getSubquery() != null) {
10095                                QueryTable queryTable = modelFactory.createQueryTable(tableElement);
10096                                TSelectSqlStatement subquery = tableElement.getSubquery();
10097                                analyzeSelectStmt(subquery);
10098
10099                                if (subquery.getSetOperatorType() != ESetOperatorType.none) {
10100                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager.getModel(subquery);
10101                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
10102                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
10103                                                ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
10104                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
10105                                                selectSetRalation.setEffectType(EffectType.select);
10106                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
10107                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
10108                                                selectSetRalation.setProcess(process);
10109                                        }
10110                                }
10111
10112                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(tableElement.getSubquery());
10113                                if (resultSetModel != null && resultSetModel != queryTable
10114                                                && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10115                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10116                                        impactRelation.setEffectType(EffectType.update);
10117                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10118                                                        resultSetModel.getRelationRows()));
10119                                        impactRelation.setTarget(
10120                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(queryTable.getRelationRows()));
10121                                }
10122
10123                        } else if (tableElement.getCTE() != null) {
10124                                QueryTable queryTable = modelFactory.createQueryTable(tableElement);
10125
10126                                TObjectNameList cteColumns = tableElement.getCTE().getColumnList();
10127                                if (cteColumns != null) {
10128                                        for (int j = 0; j < cteColumns.size(); j++) {
10129                                                modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
10130                                        }
10131                                }
10132                                TSelectSqlStatement subquery = tableElement.getCTE().getSubquery();
10133                                if (subquery != null && !stmtStack.contains(subquery)) {
10134                                        analyzeSelectStmt(subquery);
10135
10136                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
10137                                        if (resultSetModel != null && resultSetModel != queryTable
10138                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10139                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10140                                                impactRelation.setEffectType(EffectType.select);
10141                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10142                                                                resultSetModel.getRelationRows()));
10143                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10144                                                                queryTable.getRelationRows()));
10145                                        }
10146
10147                                        if (subquery.getSetOperatorType() != ESetOperatorType.none) {
10148                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
10149                                                                .getModel(subquery);
10150                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
10151                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
10152                                                        ResultColumn targetColumn = null;
10153                                                        if (cteColumns != null) {
10154                                                                targetColumn = queryTable.getColumns().get(j);
10155                                                        } else {
10156                                                                targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
10157                                                        }
10158                                                        for (Set<TObjectName> starLinkColumns : sourceColumn.getStarLinkColumns().values()) {
10159                                                                for (TObjectName starLinkColumn : starLinkColumns) {
10160                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
10161                                                                }
10162                                                        }
10163                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
10164                                                        selectSetRalation.setEffectType(EffectType.select);
10165                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
10166                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
10167                                                        selectSetRalation.setProcess(process);
10168                                                }
10169                                        } else {
10170                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
10171                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
10172                                                        ResultColumn targetColumn = null;
10173                                                        if (cteColumns != null) {
10174                                                                targetColumn = queryTable.getColumns().get(j);
10175                                                        } else {
10176                                                                targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
10177                                                        }
10178                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
10179                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
10180                                                        }
10181                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
10182                                                        selectSetRalation.setEffectType(EffectType.select);
10183                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
10184                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
10185                                                        selectSetRalation.setProcess(process);
10186                                                }
10187                                        }
10188                                } else if (tableElement.getCTE().getUpdateStmt() != null) {
10189                                        analyzeCustomSqlStmt(tableElement.getCTE().getUpdateStmt());
10190                                } else if (tableElement.getCTE().getInsertStmt() != null) {
10191                                        analyzeCustomSqlStmt(tableElement.getCTE().getInsertStmt());
10192                                } else if (tableElement.getCTE().getDeleteStmt() != null) {
10193                                        analyzeCustomSqlStmt(tableElement.getCTE().getDeleteStmt());
10194                                }
10195                        } else {
10196                                modelFactory.createTable(stmt.tables.getTable(i));
10197                        }
10198                }
10199
10200                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
10201                        TResultColumn field = stmt.getResultColumnList().getResultColumn(i);
10202
10203                        if (field.getExpr().getExpressionType() == EExpressionType.function_t) {
10204                                continue;
10205                        }
10206
10207                        TExpression expression = field.getExpr().getLeftOperand();
10208                        if (expression == null) {
10209                                ErrorInfo errorInfo = new ErrorInfo();
10210                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
10211                                errorInfo.setErrorMessage(
10212                                                "Can't get result column expression. Expression is " + field.getExpr().toString());
10213                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(field.getExpr().getStartToken().lineNo,
10214                                                field.getExpr().getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
10215                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(field.getExpr().getEndToken().lineNo,
10216                                                field.getExpr().getEndToken().columnNo + field.getExpr().getEndToken().getAstext().length(),
10217                                                ModelBindingManager.getGlobalHash()));
10218                                errorInfo.fillInfo(this);
10219                                errorInfos.add(errorInfo);
10220                                continue;
10221                        }
10222                        if (expression.getExpressionType() == EExpressionType.list_t) {
10223                                TExpression setExpression = field.getExpr().getRightOperand();
10224                                if (setExpression != null && setExpression.getSubQuery() != null) {
10225                                        TSelectSqlStatement query = setExpression.getSubQuery();
10226                                        analyzeSelectStmt(query);
10227
10228                                        SelectResultSet resultSetModel = (SelectResultSet) modelManager
10229                                                        .getModel(query.getResultColumnList());
10230
10231                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10232                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10233                                                impactRelation.setEffectType(EffectType.update);
10234                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10235                                                                resultSetModel.getRelationRows()));
10236                                                impactRelation.setTarget(
10237                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
10238                                        }
10239
10240                                        TExpressionList columnList = expression.getExprList();
10241                                        for (int j = 0; j < columnList.size(); j++) {
10242                                                TObjectName column = columnList.getExpression(j).getObjectOperand();
10243
10244                                                if (column.getDbObjectType() == EDbObjectType.variable) {
10245                                                        continue;
10246                                                }
10247
10248                                                if (column.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql
10249                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
10250                                                        continue;
10251                                                }
10252
10253                                                if (column.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana
10254                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
10255                                                        continue;
10256                                                }
10257
10258                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
10259                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false);
10260                                                if (tableColumn != null) {
10261                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10262                                                        relation.setEffectType(EffectType.update);
10263                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
10264                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10265                                                        relation.setProcess(process);
10266                                                }
10267
10268                                        }
10269                                }
10270                        } else if (expression.getExpressionType() == EExpressionType.simple_object_name_t) {
10271                                TExpression setExpression = field.getExpr().getRightOperand();
10272                                if (setExpression != null && setExpression.getSubQuery() != null) {
10273                                        TSelectSqlStatement query = setExpression.getSubQuery();
10274                                        analyzeSelectStmt(query);
10275
10276                                        SelectResultSet resultSetModel = (SelectResultSet) modelManager
10277                                                        .getModel(query.getResultColumnList());
10278
10279                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10280                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10281                                                impactRelation.setEffectType(EffectType.update);
10282                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10283                                                                resultSetModel.getRelationRows()));
10284                                                impactRelation.setTarget(
10285                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
10286                                        }
10287
10288                                        TObjectName column = expression.getObjectOperand();
10289                                        ResultColumn resultColumn = resultSetModel.getColumns().get(0);
10290                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false);
10291                                        if (tableColumn != null) {
10292                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10293                                                relation.setEffectType(EffectType.update);
10294                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
10295                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10296                                                relation.setProcess(process);
10297                                        }
10298                                } else if (setExpression != null) {
10299                                        // ResultSet resultSet = modelFactory.createResultSet(stmt,
10300                                        // true);
10301
10302                                        ResultSet resultSet = modelFactory.createResultSet(stmt, false);
10303
10304                                        createPseudoImpactRelation(stmt, resultSet, EffectType.update);
10305
10306                                        TObjectName columnObject = expression.getObjectOperand();
10307
10308                                        ResultColumn updateColumn = modelFactory.createUpdateResultColumn(resultSet, columnObject);
10309
10310                                        columnsInExpr visitor = new columnsInExpr();
10311                                        field.getExpr().getRightOperand().inOrderTraverse(visitor);
10312
10313                                        List<TObjectName> objectNames = visitor.getObjectNames();
10314                                        List<TParseTreeNode> functions = visitor.getFunctions();
10315                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
10316
10317                                        if (functions != null && !functions.isEmpty()) {
10318                                                analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.update);
10319                                        }
10320
10321                                        if (subquerys != null && !subquerys.isEmpty()) {
10322                                                analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.update);
10323                                        }
10324
10325                                        Transform transform = new Transform();
10326                                        transform.setType(Transform.EXPRESSION);
10327                                        transform.setCode(setExpression);
10328                                        updateColumn.setTransform(transform);
10329                                        analyzeDataFlowRelation(updateColumn, objectNames, EffectType.update, functions);
10330
10331                                        List<TParseTreeNode> constants = visitor.getConstants();
10332                                        analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.update, functions);
10333
10334                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false);
10335                                        if(tableColumn!=null) {
10336                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10337                                                relation.setEffectType(EffectType.update);
10338                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
10339                                                relation.addSource(new ResultColumnRelationshipElement(updateColumn));
10340                                                relation.setProcess(process);
10341                                        }
10342                                        
10343                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10344                                        impactRelation.setEffectType(EffectType.update);
10345                                        impactRelation.addSource(
10346                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
10347                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
10348                                                        tableModel.getRelationRows()));
10349                                }
10350                        }
10351                }
10352
10353                if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
10354                        for (int i = 0; i < stmt.getJoins().size(); i++) {
10355                                TJoin join = stmt.getJoins().getJoin(i);
10356                                if (join.getJoinItems() != null) {
10357                                        for (int j = 0; j < join.getJoinItems().size(); j++) {
10358                                                TJoinItem joinItem = join.getJoinItems().getJoinItem(j);
10359                                                TExpression expr = joinItem.getOnCondition();
10360                                                analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on,
10361                                                                EffectType.update);
10362                                        }
10363                                }
10364                        }
10365                }
10366
10367                if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) {
10368                        analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where,
10369                                        EffectType.update);
10370                }
10371
10372                if (stmt.getOutputClause() != null) {
10373                        TOutputClause outputClause = stmt.getOutputClause();
10374                        if (outputClause.getSelectItemList() != null) {
10375                                ResultSet resultSet = modelFactory.createResultSet(outputClause, false);
10376                                for (int j = 0; j < outputClause.getSelectItemList().size(); j++) {
10377                                        TResultColumn sourceColumn = outputClause.getSelectItemList().getResultColumn(j);
10378                                        ResultColumn sourceColumnModel = modelFactory.createResultColumn(resultSet, sourceColumn);
10379                                        analyzeResultColumn(sourceColumn, EffectType.select);
10380
10381                                        if (outputClause.getIntoTable() != null) {
10382                                                Table intoTableModel = modelFactory.createTableByName(outputClause.getIntoTable());
10383                                                intoTableModel.addProcess(process);
10384                                                if (outputClause.getIntoColumnList() != null) {
10385                                                        TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel,
10386                                                                        outputClause.getIntoColumnList().getObjectName(j));
10387
10388                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10389                                                        relation.setEffectType(EffectType.insert);
10390                                                        relation.setTarget(new TableColumnRelationshipElement(intoTableColumn));
10391                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel));
10392                                                } else if (sourceColumn.getAliasClause() != null
10393                                                                || sourceColumn.getExpr().getObjectOperand() != null) {
10394                                                        TObjectName tableColumnObject = null;
10395                                                        if (sourceColumn.getAliasClause() != null) {
10396                                                                tableColumnObject = sourceColumn.getAliasClause().getAliasName();
10397                                                        } else {
10398                                                                tableColumnObject = sourceColumn.getExpr().getObjectOperand();
10399                                                        }
10400
10401                                                        TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel,
10402                                                                        tableColumnObject);
10403                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10404                                                        relation.setEffectType(EffectType.insert);
10405                                                        relation.setTarget(new TableColumnRelationshipElement(intoTableColumn));
10406                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel));
10407                                                }
10408                                        }
10409                                }
10410                        }
10411                }
10412        }
10413
10414        private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants,
10415                        EffectType effectType, List<TParseTreeNode> functions) {
10416                analyzeConstantDataFlowRelation(modelObject, constants, effectType, functions, null);
10417        }
10418
10419        private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants,
10420                        EffectType effectType, List<TParseTreeNode> functions, Process process) {
10421                if (constants == null || constants.size() == 0)
10422                        return;
10423
10424                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10425                relation.setEffectType(effectType);
10426                relation.setProcess(process);
10427
10428                if (functions != null && !functions.isEmpty()) {
10429                        relation.setFunction(getFunctionName(functions.get(0)));
10430                }
10431
10432                if (modelObject instanceof ResultColumn) {
10433                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
10434
10435                } else if (modelObject instanceof TableColumn) {
10436                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
10437
10438                } else {
10439                        throw new UnsupportedOperationException();
10440                }
10441
10442                if (option.isShowConstantTable()) {
10443                        Table constantTable = null;
10444                        if(modelObject instanceof FunctionResultColumn && ((FunctionResultColumn)modelObject).getFunction() instanceof TFunctionCall) {
10445                                TFunctionCall function = (TFunctionCall)((FunctionResultColumn)modelObject).getFunction();
10446                                if(function.getFunctionType() == EFunctionType.struct_t) {
10447                                        constantTable = modelFactory.createConstantsTable(String.valueOf(function.toString().hashCode()));
10448                                }
10449                        }
10450                        if(constantTable == null) {
10451                                constantTable = modelFactory.createConstantsTable(stmtStack.peek());
10452                        }
10453                        for (int i = 0; i < constants.size(); i++) {
10454                                TParseTreeNode constant = constants.get(i);
10455                                if (constant instanceof TConstant) {
10456                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TConstant) constant);
10457                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
10458                                } else if (constant instanceof TObjectName) {
10459                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TObjectName) constant,
10460                                                        false);
10461                                        if(constantColumn == null) {
10462                                                continue;
10463                                        }
10464                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
10465                                }
10466                        }
10467                }
10468
10469        }
10470
10471        private String getFunctionName(TParseTreeNode parseTreeNode) {
10472                if (parseTreeNode instanceof TFunctionCall) {
10473                        return ((TFunctionCall) parseTreeNode).getFunctionName().toString();
10474                }
10475                if (parseTreeNode instanceof TCaseExpression) {
10476                        return "case-when";
10477                }
10478                return null;
10479        }
10480
10481        private void analyzeCreateViewStmt(TCustomSqlStatement stmt, TSelectSqlStatement subquery,
10482                        TViewAliasClause viewAlias, TObjectName viewName) {
10483
10484                if (subquery != null) {
10485                        TTableList tables = subquery.getTables();
10486                        if (tables != null) {
10487                                for (int i = 0; i < tables.size(); i++) {
10488                                        TTable table = tables.getTable(i);
10489                                        TCustomSqlStatement createView = viewDDLMap
10490                                                        .get(DlineageUtil.getTableFullName(table.getTableName().toString()));
10491                                        if (createView != null) {
10492                                                analyzeCustomSqlStmt(createView);
10493                                        }
10494                                }
10495                        }
10496                        analyzeSelectStmt(subquery);
10497                }
10498
10499        
10500                if (viewAlias != null && viewAlias.getViewAliasItemList() != null) {
10501                        TViewAliasItemList viewItems = viewAlias.getViewAliasItemList();
10502                        Table viewModel = modelFactory.createView(stmt, viewName, true);
10503                        viewModel.setFromDDL(true);
10504                        viewModel.setDetermined(true);
10505                        Process process = modelFactory.createProcess(stmt);
10506                        viewModel.addProcess(process);
10507                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
10508                        if (resultSetModel != null) {
10509                                int resultSetSize = resultSetModel.getColumns().size();
10510                                int viewItemSize = viewItems.size();
10511                                int j = 0;
10512                                int viewColumnSize = viewItemSize;
10513                                if (resultSetModel.isDetermined() && resultSetSize > viewColumnSize) {
10514                                        viewColumnSize = resultSetSize;
10515                                }
10516                                for (int i = 0; i < viewColumnSize && j < resultSetSize; i++) {
10517                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);                                 
10518                                        if (i < viewItemSize) {
10519                                                TObjectName alias = viewItems.getViewAliasItem(i).getAlias();
10520
10521                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
10522                                                        j++;
10523                                                } else {
10524                                                        if (resultSetSize - j == viewItems.size() - i) {
10525                                                                j++;
10526                                                        }
10527                                                }
10528
10529                                                if (alias != null) {
10530                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true);
10531                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10532                                                        if (resultColumn != null) {
10533                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10534                                                                relation.setEffectType(EffectType.create_view);
10535                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10536                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10537                                                                relation.setProcess(process);
10538                                                        }
10539                                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
10540                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10541                                                                        (TObjectName) resultColumn.getColumnObject(), i, true);
10542                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10543                                                        if (resultColumn != null) {
10544                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10545                                                                relation.setEffectType(EffectType.create_view);
10546                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10547                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10548                                                                relation.setProcess(process);
10549                                                        }
10550                                                } else if (resultColumn.getColumnObject() instanceof TResultColumn) {
10551                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10552                                                                        ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), i, true);
10553                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10554                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
10555                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
10556                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
10557                                                        }
10558                                                        if (resultColumn != null) {
10559                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10560                                                                relation.setEffectType(EffectType.create_view);
10561                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10562                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10563                                                                relation.setProcess(process);
10564                                                        }
10565                                                }
10566                                        }
10567                                        else if(resultSetModel.isDetermined()){
10568                                                TObjectName viewColumnName = new TObjectName();
10569                                                viewColumnName.setString(resultColumn.getName());
10570                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, viewModel.getColumns().size(), true);
10571                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10572                                                relation.setEffectType(EffectType.create_view);
10573                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10574                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10575                                                relation.setProcess(process);
10576                                                j++;
10577                                        }
10578                                }
10579                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10580                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10581                                        impactRelation.setEffectType(EffectType.create_view);
10582                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10583                                                        resultSetModel.getRelationRows()));
10584                                        impactRelation.setTarget(
10585                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
10586                                }
10587                        }
10588
10589                        if (subquery.getResultColumnList() == null && subquery.getValueClause() != null
10590                                        && subquery.getValueClause().getValueRows().size() == viewItems.size()) {
10591                                for (int i = 0; i < viewItems.size(); i++) {
10592                                        TObjectName alias = viewItems.getViewAliasItem(i).getAlias();
10593
10594                                        if (alias != null) {
10595                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true);
10596                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10597                                                TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr();
10598
10599                                                columnsInExpr visitor = new columnsInExpr();
10600                                                expression.inOrderTraverse(visitor);
10601                                                List<TObjectName> objectNames = visitor.getObjectNames();
10602                                                List<TParseTreeNode> functions = visitor.getFunctions();
10603
10604                                                if (functions != null && !functions.isEmpty()) {
10605                                                        analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select);
10606
10607                                                }
10608
10609                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
10610                                                if (subquerys != null && !subquerys.isEmpty()) {
10611                                                        analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select);
10612                                                }
10613
10614                                                analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions);
10615                                                List<TParseTreeNode> constants = visitor.getConstants();
10616                                                analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions);
10617                                        }
10618                                }
10619                        }
10620
10621                } else {
10622                        if (viewName == null) {
10623                                ErrorInfo errorInfo = new ErrorInfo();
10624                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
10625                                errorInfo.setErrorMessage("Can't get view name. CreateView is " + stmt.toString());
10626                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
10627                                                stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
10628                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
10629                                                stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
10630                                                ModelBindingManager.getGlobalHash()));
10631                                errorInfo.fillInfo(this);
10632                                errorInfos.add(errorInfo);
10633                                return;
10634                        }
10635                        Table viewModel = modelFactory.createView(stmt, viewName);
10636                        Process process = modelFactory.createProcess(stmt);
10637                        viewModel.addProcess(process);
10638                        if (subquery != null && !subquery.isCombinedQuery()) {
10639                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
10640                                                .getModel(subquery.getResultColumnList());
10641
10642                                boolean determined = false;
10643                                if (!containStarColumn(resultSetModel)) {
10644                                        viewModel.setCreateTable(true);
10645                                        determined = true;
10646                                        viewModel.setFromDDL(true);
10647                                }
10648                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
10649                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
10650                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
10651                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
10652
10653                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
10654                                                if (alias != null && alias.getAliasName() != null) {
10655                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i,
10656                                                                        determined);
10657                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10658                                                        relation.setEffectType(EffectType.create_view);
10659                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10660                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10661                                                        relation.setProcess(process);
10662                                                        if (determined) {
10663                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10664                                                        }
10665                                                } else if (columnObject.getFieldAttr() != null) {
10666                                                        TObjectName viewColumnObject = columnObject.getFieldAttr();
10667                                                        TableColumn viewColumn;
10668                                                        Object model = modelManager.getModel(resultColumn.getColumnObject());
10669                                                        if ("*".equals(viewColumnObject.getColumnNameOnly())) {
10670                                                                if (model instanceof LinkedHashMap) {
10671                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
10672                                                                        LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model;
10673                                                                        if ("*".equals(columnName)) {
10674                                                                                for (String key : resultColumns.keySet()) {
10675                                                                                        ResultColumn column = resultColumns.get(key);
10676                                                                                        viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName());
10677                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10678                                                                                        relation.setEffectType(EffectType.create_view);
10679                                                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10680                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
10681                                                                                        relation.setProcess(process);
10682                                                                                }
10683                                                                                continue;
10684                                                                        } else if (resultColumns.containsKey(columnName)) {
10685                                                                                ResultColumn column = resultColumns.get(columnName);
10686                                                                                viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName());
10687                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10688                                                                                relation.setEffectType(EffectType.create_view);
10689                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10690                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
10691                                                                                relation.setProcess(process);
10692                                                                                continue;
10693                                                                        }
10694                                                                }
10695                                                        }
10696                                                        
10697                                                        if (!SQLUtil.isEmpty(viewColumnObject.getColumnNameOnly())
10698                                                                        && viewColumnObject.getPropertyToken() != null) {
10699                                                                TObjectName object = new TObjectName();
10700                                                                // object.setString(viewColumnObject.getPropertyToken().astext);
10701                                                                object.setPartToken(viewColumnObject.getPropertyToken());
10702                                                                object.setStartToken(viewColumnObject.getPropertyToken());
10703                                                                object.setEndToken(viewColumnObject.getPropertyToken());
10704                                                                viewColumn = modelFactory.createViewColumn(viewModel, object, i, determined);
10705                                                        } else {
10706                                                                viewColumn = modelFactory.createViewColumn(viewModel, columnObject.getFieldAttr(),
10707                                                                                i, determined);
10708                                                        }
10709                                                        
10710                                                        if(determined) {
10711                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10712                                                        }
10713                                                        
10714                                                        if (model instanceof ResultColumn) {
10715                                                                ResultColumn column = (ResultColumn) modelManager
10716                                                                                .getModel(resultColumn.getColumnObject());
10717                                                                if (column != null && !column.getStarLinkColumns().isEmpty()) {
10718                                                                        viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
10719                                                                }
10720                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10721                                                                relation.setEffectType(EffectType.create_view);
10722                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10723                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10724                                                                if (sqlenv == null) {
10725                                                                        if (resultColumn.isShowStar()) {
10726                                                                                relation.setShowStarRelation(true);
10727                                                                                viewColumn.setShowStar(true);
10728                                                                                resultColumn.setShowStar(true);
10729                                                                                setSourceShowStar(resultColumn);
10730                                                                        }
10731                                                                }
10732                                                                if (viewColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
10733                                                                        viewModel.setStarStmt("create_view");
10734                                                                }
10735                                                                relation.setProcess(process);
10736                                                        }
10737                                                } else if (resultColumn.getAlias() != null && columnObject.getExpr()
10738                                                                .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
10739                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10740                                                                        columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined);
10741                                                        if(determined) {
10742                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10743                                                        }
10744                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10745                                                        relation.setEffectType(EffectType.create_view);
10746                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10747                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10748                                                        relation.setProcess(process);
10749                                                } else {
10750                                                        TGSqlParser parser = columnObject.getGsqlparser();
10751                                                        TObjectName viewColumnName = parser
10752                                                                        .parseObjectName(generateQuotedName(parser, columnObject.toString()));
10753                                                        if (viewColumnName == null) {
10754                                                                ErrorInfo errorInfo = new ErrorInfo();
10755                                                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
10756                                                                errorInfo.setErrorMessage(
10757                                                                                "Can't parse view column. Column is " + columnObject.toString());
10758                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(
10759                                                                                columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo,
10760                                                                                ModelBindingManager.getGlobalHash()));
10761                                                                errorInfo
10762                                                                                .setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo,
10763                                                                                                columnObject.getEndToken().columnNo
10764                                                                                                                + columnObject.getEndToken().getAstext().length(),
10765                                                                                                ModelBindingManager.getGlobalHash()));
10766                                                                errorInfo.fillInfo(this);
10767                                                                errorInfos.add(errorInfo);
10768                                                        } else {
10769                                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i,
10770                                                                                determined);
10771                                                                if(determined) {
10772                                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10773                                                                }
10774                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10775                                                                relation.setEffectType(EffectType.create_view);
10776                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10777                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10778                                                                relation.setProcess(process);
10779                                                        }
10780                                                }
10781                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
10782                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10783                                                                (TObjectName) resultColumn.getColumnObject(), i, determined);
10784                                                if(determined) {
10785                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10786                                                }
10787                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10788                                                relation.setEffectType(EffectType.create_view);
10789                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10790                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10791                                                relation.setProcess(process);
10792                                        }
10793                                }
10794                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10795                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10796                                        impactRelation.setEffectType(EffectType.create_view);
10797                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10798                                                        resultSetModel.getRelationRows()));
10799                                        impactRelation.setTarget(
10800                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
10801                                }
10802                        } else if (subquery != null && subquery.isCombinedQuery()) {
10803                                SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(subquery);
10804
10805                                boolean determined = false;
10806                                if (!containStarColumn(resultSetModel)) {
10807                                        viewModel.setCreateTable(true);
10808                                        viewModel.setFromDDL(true);
10809                                        determined = true;
10810                                }
10811
10812                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
10813                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
10814
10815                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
10816                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
10817
10818                                                TAliasClause alias = columnObject.getAliasClause();
10819                                                if (alias != null && alias.getAliasName() != null) {
10820                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i,
10821                                                                        determined);
10822                                                        if(determined) {
10823                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10824                                                        }
10825                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10826                                                        relation.setEffectType(EffectType.create_view);
10827                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10828                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10829                                                        relation.setProcess(process);
10830                                                } else if (columnObject.getFieldAttr() != null) {
10831                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10832                                                                        columnObject.getFieldAttr(), i, determined);
10833                                                        if(determined) {
10834                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10835                                                        }
10836                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
10837                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
10838                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
10839                                                        }
10840                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10841                                                        relation.setEffectType(EffectType.create_view);
10842                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10843                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10844                                                        relation.setProcess(process);
10845                                                } else if (resultColumn.getAlias() != null && columnObject.getExpr()
10846                                                                .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
10847                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10848                                                                        columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined);
10849                                                        if(determined) {
10850                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10851                                                        }
10852                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10853                                                        relation.setEffectType(EffectType.create_view);
10854                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10855                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10856                                                        relation.setProcess(process);
10857                                                } else {
10858                                                        TGSqlParser parser = columnObject.getGsqlparser();
10859                                                        TObjectName viewColumnName = parser
10860                                                                        .parseObjectName(generateQuotedName(parser, columnObject.toString()));
10861                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i,
10862                                                                        determined);
10863                                                        if(determined) {
10864                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10865                                                        }
10866                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10867                                                        relation.setEffectType(EffectType.create_view);
10868                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10869                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10870                                                        relation.setProcess(process);
10871                                                }
10872                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
10873                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10874                                                                (TObjectName) resultColumn.getColumnObject(), i, determined);
10875                                                if(viewColumn!=null) {
10876                                                        if(determined) {
10877                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10878                                                        }
10879                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10880                                                        relation.setEffectType(EffectType.create_view);
10881                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10882                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10883                                                        relation.setProcess(process);
10884                                                }
10885                                        }
10886                                }
10887                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10888                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10889                                        impactRelation.setEffectType(EffectType.create_view);
10890                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10891                                                        resultSetModel.getRelationRows()));
10892                                        impactRelation.setTarget(
10893                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
10894                                }
10895                        }
10896                }
10897        }
10898
10899        private void setSourceShowStar(Object resultColumn) {
10900                for (Relationship relation : modelManager.getRelations()) {
10901                        Collection<RelationshipElement<?>> sources = (Collection<RelationshipElement<?>>)relation.getSources();
10902                        if (relation.getTarget().getElement() == resultColumn && sources != null) {
10903
10904                                ((AbstractRelationship) relation).setShowStarRelation(true);
10905                                for (RelationshipElement<?> source : sources) {
10906                                        Object column = source.getElement();
10907                                        if (column instanceof TableColumn) {
10908                                                if (((TableColumn) column).isShowStar())
10909                                                        continue;
10910                                                ((TableColumn) column).setShowStar(true);
10911                                        }
10912                                        if (column instanceof ResultColumn) {
10913                                                if (((ResultColumn) column).isShowStar())
10914                                                        continue;
10915                                                ((ResultColumn) column).setShowStar(true);
10916                                        }
10917                                        setSourceShowStar(column);
10918                                }
10919                        }
10920                }
10921        }
10922
10923        private String generateQuotedName(TGSqlParser parser, String name) {
10924                return "\"" + name + "\"";
10925        }
10926
10927        private void appendRelations(dataflow dataflow) {
10928                Relationship[] relations = modelManager.getRelations();
10929
10930                appendRelation(dataflow, relations, DataFlowRelationship.class);
10931                appendRelation(dataflow, relations, IndirectImpactRelationship.class);
10932                appendRecordSetRelation(dataflow, relations);
10933                appendCallRelation(dataflow, relations);
10934                appendRelation(dataflow, relations, ImpactRelationship.class);
10935                appendRelation(dataflow, relations, JoinRelationship.class);
10936                appendRelation(dataflow, relations, ERRelationship.class);
10937                appendRelation(dataflow, relations, CrudRelationship.class);
10938        }
10939
10940        private Set<String> appendStarColumns = new HashSet<String>();
10941        private void appendRelation(dataflow dataflow, Relationship[] relations, Class<? extends Relationship> clazz) {
10942                for (int i = 0; i < relations.length; i++) {
10943                        AbstractRelationship relation = (AbstractRelationship) relations[i];
10944                        if (relation.getClass() == clazz) {
10945                                if (relation.getSources() == null || relation.getTarget() == null) {
10946                                        continue;
10947                                }
10948                                Object targetElement = relation.getTarget().getElement();
10949                                TObjectName targetColumnName = null;
10950                                if(relation.getTarget() instanceof ResultColumnRelationshipElement) {
10951                                        targetColumnName = ((ResultColumnRelationshipElement) relation.getTarget()).getColumnName();
10952                                }
10953                                if (targetElement instanceof ResultColumn) {
10954                                        ResultColumn targetColumn = (ResultColumn) targetElement;
10955                                        if (!targetColumn.isPseduo()) 
10956                                        {
10957                                                if (targetColumnName == null) 
10958                                                {
10959                                                        if ("*".equals(targetColumn.getName())) {
10960                                                                updateResultColumnStarLinks(dataflow, relation, -1);
10961                                                        }
10962
10963                                                        if (targetColumn.hasStarLinkColumn()) {
10964                                                                for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) {
10965                                                                        appendStarRelation(dataflow, relation, j);
10966                                                                }
10967
10968                                                                if (!containsStar(relation.getSources())) {
10969                                                                        continue;
10970                                                                }
10971                                                        }
10972                                                }
10973                                                else {
10974                                                        String columnName = DlineageUtil.getColumnName(targetColumnName);
10975                                                        int index = targetColumn.getStarLinkColumnNames().indexOf(columnName);
10976                                                        if (index != -1) {
10977                                                                int size = targetColumn.getStarLinkColumnNames().size();
10978                                                                if ("*".equals(targetColumn.getName())) {
10979                                                                        if (appendStarColumns.contains(columnName)) {
10980                                                                                updateResultColumnStarLinks(dataflow, relation, index);
10981                                                                        }
10982                                                                        else {
10983                                                                                updateResultColumnStarLinks(dataflow, relation, -1);
10984                                                                                appendStarColumns.add(columnName);
10985                                                                        }
10986                                                                }
10987                                                                appendStarRelation(dataflow, relation, index);
10988                                                                for(int j= size; j < targetColumn.getStarLinkColumnNames().size(); j++) {
10989                                                                        appendStarRelation(dataflow, relation, j);
10990                                                                }
10991                                                                if (!containsStar(relation.getSources())) {
10992                                                                        continue;
10993                                                                }
10994                                                        }
10995                                                }
10996                                        }
10997                                } else if (targetElement instanceof TableColumn) {
10998                                        TableColumn targetColumn = (TableColumn) targetElement;
10999                                        if (!targetColumn.isPseduo()) {
11000                                                if ("*".equals(targetColumn.getName())) {
11001                                                        updateTableColumnStarLinks(dataflow, relation);
11002                                                }
11003
11004                                                if (targetColumn.hasStarLinkColumn() && !targetColumn.isVariant()
11005                                                                && targetColumn.isExpandStar()) {
11006                                                        for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) {
11007                                                                appendStarRelation(dataflow, relation, j);
11008                                                        }
11009                                                        if (!containsStar(relation.getSources())) {
11010                                                                continue;
11011                                                        }
11012                                                }
11013                                        }
11014                                }
11015
11016                                relationship relationElement = new relationship();
11017                                relationElement.setType(relation.getRelationshipType().name());
11018                                if (relation.getEffectType() != null) {
11019                                        relationElement.setEffectType(relation.getEffectType().name());
11020                                }
11021                                if (relation.getFunction() != null) {
11022                                        relationElement.setFunction(relation.getFunction());
11023                                }
11024                                relationElement.setSqlHash(relation.getSqlHash());
11025                                relationElement.setSqlComment(relation.getSqlComment());
11026
11027                                if (relation.getProcedureId() != null) {
11028                                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11029                                }
11030                                relationElement.setId(String.valueOf(relation.getId()));
11031                                if (relation.getProcess() != null) {
11032                                        relationElement.setProcessId(String.valueOf(relation.getProcess().getId()));
11033                                        if (relation.getProcess().getGspObject() != null) {
11034                                                relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name());
11035                                        }
11036                                }
11037
11038                                if (relation.getPartition() != null) {
11039                                        relationElement.setPartition(relation.getPartition());
11040                                }
11041                                relationElement.setSqlHash(relation.getSqlHash());
11042                                relationElement.setSqlComment(relation.getSqlComment());
11043                                
11044                                if (relation.getProcedureId() != null) {
11045                                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11046                                }
11047                                
11048                                if (relation instanceof JoinRelationship) {
11049                                        relationElement.setCondition(((JoinRelationship) relation).getJoinCondition());
11050                                        relationElement.setJoinType(((JoinRelationship) relation).getJoinType().name());
11051                                        relationElement.setClause(((JoinRelationship) relation).getJoinClauseType().name());
11052                                }
11053
11054                                if(relation instanceof ImpactRelationship){
11055                                        ImpactRelationship impactRelationship = (ImpactRelationship)relation;
11056                                        if(impactRelationship.getJoinClauseType()!=null){
11057                                                relationElement.setClause(impactRelationship.getJoinClauseType().name());
11058                                        }
11059                                }
11060
11061                                String targetName = null;
11062                                Object columnObject = null;
11063                                List<TObjectName> targetObjectNames = null;
11064
11065                                if (targetElement instanceof ResultSetRelationRows) {
11066                                        ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement;
11067                                        targetColumn target = new targetColumn();
11068                                        target.setId(String.valueOf(targetColumn.getId()));
11069                                        target.setColumn(targetColumn.getName());
11070                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
11071                                        target.setParent_name(getResultSetName(targetColumn.getHolder()));
11072                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11073                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11074                                                                + convertCoordinate(targetColumn.getEndPosition()));
11075                                        }
11076                                        if (relation instanceof RecordSetRelationship) {
11077                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11078                                        }
11079                                        target.setSource("system");
11080                                        targetName = targetColumn.getName();
11081                                        relationElement.setTarget(target);
11082                                } else if (targetElement instanceof TableRelationRows) {
11083                                        TableRelationRows targetColumn = (TableRelationRows) targetElement;
11084                                        targetColumn target = new targetColumn();
11085                                        target.setId(String.valueOf(targetColumn.getId()));
11086                                        target.setColumn(targetColumn.getName());
11087                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
11088                                        target.setParent_name(getTableName(targetColumn.getHolder()));
11089                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11090                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11091                                                                + convertCoordinate(targetColumn.getEndPosition()));
11092                                        }
11093                                        if (relation instanceof RecordSetRelationship) {
11094                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11095                                        }
11096                                        target.setSource("system");
11097                                        targetName = targetColumn.getName();
11098                                        relationElement.setTarget(target);
11099                                } else if (targetElement instanceof ResultColumn) {
11100                                        ResultColumn targetColumn = (ResultColumn) targetElement;
11101                                        targetColumn target = new targetColumn();
11102                                        target.setId(String.valueOf(targetColumn.getId()));
11103                                        target.setColumn(targetColumn.getName());
11104                                        target.setStruct(targetColumn.isStruct());
11105                                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
11106                                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
11107                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11108                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11109                                                                + convertCoordinate(targetColumn.getEndPosition()));
11110                                        }
11111                                        if (relation instanceof RecordSetRelationship) {
11112                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11113                                        }
11114                                        targetName = targetColumn.getName();
11115                                        if (((ResultColumn) targetColumn).getColumnObject() instanceof TResultColumn) {
11116                                                columnsInExpr visitor = new columnsInExpr();
11117                                                ((TResultColumn) ((ResultColumn) targetColumn).getColumnObject()).getExpr()
11118                                                                .inOrderTraverse(visitor);
11119                                                targetObjectNames = visitor.getObjectNames();
11120                                        }
11121
11122                                        if (targetElement instanceof FunctionResultColumn) {
11123                                                columnObject = ((FunctionResultColumn) targetElement).getColumnObject();
11124                                        }
11125                                        if(targetColumn.isPseduo()) {
11126                                                target.setSource("system");
11127                                        }
11128                                        relationElement.setTarget(target);
11129                                } else if (targetElement instanceof TableColumn) {
11130                                        TableColumn targetColumn = (TableColumn) targetElement;
11131                                        targetColumn target = new targetColumn();
11132                                        target.setId(String.valueOf(targetColumn.getId()));
11133                                        target.setColumn(targetColumn.getName());
11134                                        target.setStruct(targetColumn.isStruct());
11135                                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
11136                                        target.setParent_name(getTableName(targetColumn.getTable()));
11137                                        if (relation.getTarget() instanceof TableColumnRelationshipElement) {
11138                                                target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias());
11139                                        }
11140                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11141                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11142                                                                + convertCoordinate(targetColumn.getEndPosition()));
11143                                        }
11144                                        if (relation instanceof RecordSetRelationship) {
11145                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11146                                        }
11147                                        if(targetColumn.isPseduo()) {
11148                                                target.setSource("system");
11149                                        }
11150                                        targetName = targetColumn.getName();
11151                                        relationElement.setTarget(target);
11152                                } else if (targetElement instanceof Argument) {
11153                                        Argument targetColumn = (Argument) targetElement;
11154                                        targetColumn target = new targetColumn();
11155                                        target.setId(String.valueOf(targetColumn.getId()));
11156                                        target.setColumn(targetColumn.getName());
11157                                        target.setParent_id(String.valueOf(targetColumn.getProcedure().getId()));
11158                                        target.setParent_name(targetColumn.getProcedure().getName());
11159                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11160                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11161                                                                + convertCoordinate(targetColumn.getEndPosition()));
11162                                        }
11163                                        if (relation instanceof RecordSetRelationship) {
11164                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11165                                        }
11166                                        targetName = targetColumn.getName();
11167                                        relationElement.setTarget(target);
11168                                } else if (targetElement instanceof Table) {
11169                                        Table table = (Table) targetElement;
11170                                        targetColumn target = new targetColumn();
11171                                        target.setTarget_id(String.valueOf(table.getId()));
11172                                        target.setTarget_name(getTableName(table));
11173                                        if (table.getStartPosition() != null && table.getEndPosition() != null) {
11174                                                target.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
11175                                                                + convertCoordinate(table.getEndPosition()));
11176                                        }
11177                                        relationElement.setTarget(target);
11178                                } else {
11179                                        continue;
11180                                }
11181
11182                                Collection<RelationshipElement<?>> sourceElements = relation.getSources();
11183                                if (sourceElements.size() == 0) {
11184                                        if(clazz == CrudRelationship.class && option.getAnalyzeMode() == AnalyzeMode.crud) {
11185                                                dataflow.getRelationships().add(relationElement);
11186                                        }
11187                                        continue;
11188                                }
11189
11190                                boolean append = false;
11191                                for (RelationshipElement<?> sourceItem: relation.getSources()) {
11192                                        Object sourceElement = sourceItem.getElement();
11193                                        TObjectName sourceColumnName = null;
11194                                        if (sourceItem instanceof ResultColumnRelationshipElement) {
11195                                                sourceColumnName = ((ResultColumnRelationshipElement) sourceItem).getColumnName();
11196                                        }
11197//                                      if (sourceItem instanceof TableColumnRelationElement
11198//                                                      && (((TableColumnRelationElement) sourceItem).getColumnIndex() != null)) {
11199//                                              TableColumnRelationElement tableColumnRelationElement = (TableColumnRelationElement) sourceItem;
11200//                                              sourceElement = tableColumnRelationElement.getElement().getTable().getColumns()
11201//                                                              .get(tableColumnRelationElement.getColumnIndex() + 1);
11202//                                      }
11203                                        if (sourceElement instanceof ResultColumn) {
11204                                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
11205                                                if (sourceColumn.hasStarLinkColumn() && !relation.isShowStarRelation() && !sourceColumn.isPseduo()) {
11206                                                        List<String> sourceStarColumnNames = sourceColumn.getStarLinkColumnNames();
11207                                                        sourceColumn source = new sourceColumn();
11208                                                        if (targetObjectNames != null && !targetObjectNames.isEmpty()) {
11209
11210                                                                for (int k = 0; k < targetObjectNames.size(); k++) {
11211                                                                        String targetObjectName = getColumnName(targetObjectNames.get(k));
11212                                                                        if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11213                                                                                boolean find = false;
11214                                                                                for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
11215                                                                                        if(column.getName().equalsIgnoreCase(targetObjectName)) {
11216                                                                                                source = new sourceColumn();
11217                                                                                                source.setId(String.valueOf(column.getId()));
11218                                                                                                source.setColumn(targetObjectName);
11219                                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11220                                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11221                                                                                                if (sourceColumn.getStartPosition() != null
11222                                                                                                                && sourceColumn.getEndPosition() != null) {
11223                                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11224                                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
11225                                                                                                }
11226                                                                                                append = true;
11227                                                                                                relationElement.addSource(source);
11228                                                                                                find = true;
11229                                                                                                break;
11230                                                                                        }
11231                                                                                }
11232                                                                                if(find) {
11233                                                                                        continue;
11234                                                                                }
11235                                                                        }
11236                                                                        if (sourceColumn.getStarLinkColumns().containsKey(targetObjectName)) {
11237                                                                                source = new sourceColumn();
11238                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
11239                                                                                                + sourceStarColumnNames.indexOf(targetObjectName));
11240                                                                                source.setColumn(targetObjectName);
11241                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11242                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11243                                                                                if (sourceColumn.getStartPosition() != null
11244                                                                                                && sourceColumn.getEndPosition() != null) {
11245                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11246                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
11247                                                                                }
11248                                                                                append = true;
11249                                                                                relationElement.addSource(source);
11250                                                                        } else {
11251                                                                                source = new sourceColumn();
11252                                                                                source.setId(String.valueOf(sourceColumn.getId()));
11253                                                                                source.setColumn(relationElement.getTarget().getColumn());
11254                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11255                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11256                                                                                if (sourceColumn.getStartPosition() != null
11257                                                                                                && sourceColumn.getEndPosition() != null) {
11258                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11259                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
11260                                                                                }
11261                                                                                append = true;
11262                                                                                relationElement.addSource(source);
11263                                                                        }
11264                                                                }
11265                                                        } else {
11266                                                                if (columnObject instanceof TWhenClauseItemList) {
11267                                                                        TCaseExpression expr = (TCaseExpression)((FunctionResultColumn) targetElement).getResultSet().getGspObject();
11268                                                                        List<TExpression> directExpressions = new ArrayList<TExpression>();
11269                                                                        
11270//                                                                      TExpression inputExpr = expr.getInput_expr();
11271//                                                                      if (inputExpr != null) {
11272//                                                                              directExpressions.add(inputExpr);
11273//                                                                      }
11274                                                                        TExpression defaultExpr = expr.getElse_expr();
11275                                                                        if (defaultExpr != null) {
11276                                                                                directExpressions.add(defaultExpr);
11277                                                                        }
11278                                                                        TWhenClauseItemList list = expr.getWhenClauseItemList();
11279                                                                        for (int k = 0; k < list.size(); k++) {
11280                                                                                TWhenClauseItem element = list.getWhenClauseItem(k);
11281                                                                                directExpressions.add(element.getReturn_expr());
11282                                                                        }
11283                                                                        
11284                                                                        for (int k = 0; k < directExpressions.size(); k++) {
11285                                                                                columnsInExpr visitor = new columnsInExpr();
11286                                                                                directExpressions.get(k).inOrderTraverse(visitor);
11287                                                                                List<TObjectName> objectNames = visitor.getObjectNames();
11288                                                                                if (objectNames == null) {
11289                                                                                        continue;
11290                                                                                }
11291                                                                                for (int x = 0; x < objectNames.size(); x++) {
11292                                                                                        String objectName = getColumnName(objectNames.get(x));
11293                                                                                        if (sourceColumn.getStarLinkColumns().containsKey(objectName)) {
11294
11295                                                                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11296                                                                                                        boolean find = false;
11297                                                                                                        for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
11298                                                                                                                if(column.getName().equalsIgnoreCase(objectName)) {
11299                                                                                                                        source = new sourceColumn();
11300                                                                                                                        source.setId(String.valueOf(column.getId()));
11301                                                                                                                        source.setColumn(objectName);
11302                                                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11303                                                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11304                                                                                                                        if (sourceColumn.getStartPosition() != null
11305                                                                                                                                        && sourceColumn.getEndPosition() != null) {
11306                                                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11307                                                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
11308                                                                                                                        }
11309                                                                                                                        append = true;
11310                                                                                                                        relationElement.addSource(source);
11311                                                                                                                        find = true;
11312                                                                                                                        break;
11313                                                                                                                }
11314                                                                                                        }
11315                                                                                                        if(find) {
11316                                                                                                                continue;
11317                                                                                                        }
11318                                                                                                }
11319                                                                                                
11320                                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
11321                                                                                                                + sourceStarColumnNames.indexOf(objectName));
11322                                                                                                source.setColumn(objectName);
11323                                                                                        } else {
11324                                                                                                source.setId(String.valueOf(sourceColumn.getId()));
11325                                                                                                source.setColumn(sourceColumn.getName());
11326                                                                                        }
11327                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11328                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11329                                                                                        if (sourceColumn.getStartPosition() != null
11330                                                                                                        && sourceColumn.getEndPosition() != null) {
11331                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11332                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
11333                                                                                        }
11334                                                                                        append = true;
11335                                                                                        relationElement.addSource(source);
11336                                                                                }
11337                                                                        }
11338                                                                } else {
11339                                                                        String objectName = getColumnName(targetName);
11340                                                                        boolean find = false;
11341                                                                        
11342                                                                        if (!find && sourceColumn.getStarLinkColumns().containsKey(objectName)) {
11343                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
11344                                                                                                + sourceStarColumnNames.indexOf(objectName));
11345                                                                                source.setColumn(objectName);
11346                                                                                find = true;
11347                                                                        }
11348
11349                                                                        if (!find && sourceColumnName != null) {
11350                                                                                objectName = getColumnName(sourceColumnName);
11351                                                                                
11352                                                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11353                                                                                        for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
11354                                                                                                if(column.getName().equalsIgnoreCase(objectName)) {
11355                                                                                                        source = new sourceColumn();
11356                                                                                                        source.setId(String.valueOf(column.getId()));
11357                                                                                                        source.setColumn(objectName);
11358                                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11359                                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11360                                                                                                        if (sourceColumn.getStartPosition() != null
11361                                                                                                                        && sourceColumn.getEndPosition() != null) {
11362                                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11363                                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
11364                                                                                                        }
11365                                                                                                        append = true;
11366                                                                                                        relationElement.addSource(source);
11367                                                                                                        find = true;
11368                                                                                                        break;
11369                                                                                                }
11370                                                                                        }
11371                                                                                        if(find) {
11372                                                                                                continue;
11373                                                                                        }
11374                                                                                }
11375                                                                                
11376                                                                                if (sourceColumn.getStarLinkColumns().containsKey(objectName)) {
11377                                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
11378                                                                                                        + sourceStarColumnNames.indexOf(objectName));
11379                                                                                        source.setColumn(objectName);
11380                                                                                        find = true;
11381                                                                                }
11382                                                                        }
11383                                                                        
11384                                                                        if (!find && sourceItem instanceof ResultColumnRelationshipElement) {
11385                                                                                int starIndex = ((ResultColumnRelationshipElement) sourceItem)
11386                                                                                                .getStarIndex();
11387                                                                                if (starIndex > -1 && sourceColumn.getStarLinkColumnList().size() > starIndex) {
11388                                                                                        objectName = getColumnName(sourceColumn.getStarLinkColumnList().get(starIndex));
11389                                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
11390                                                                                                        + starIndex);
11391                                                                                        source.setColumn(objectName);
11392                                                                                        find = true;
11393                                                                                }
11394                                                                        }
11395
11396                                                                        if (!find) {
11397                                                                                source.setId(String.valueOf(sourceColumn.getId()));
11398                                                                                source.setColumn(sourceColumn.getName());
11399                                                                        }
11400
11401                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11402                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11403                                                                        if (sourceColumn.getStartPosition() != null
11404                                                                                        && sourceColumn.getEndPosition() != null) {
11405                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11406                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11407                                                                        }
11408                                                                        append = true;
11409                                                                        relationElement.addSource(source);
11410                                                                }
11411                                                        }
11412
11413                                                } else {
11414                                                        sourceColumn source = new sourceColumn();
11415                                                        source.setId(String.valueOf(sourceColumn.getId()));
11416                                                        source.setColumn(sourceColumn.getName());
11417                                                        source.setStruct(sourceColumn.isStruct());
11418                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11419                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11420                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11421                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11422                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11423                                                        }
11424                                                        append = true;
11425                                                        if (sourceItem.getTransforms() != null) {
11426                                                                for (Transform transform : sourceItem.getTransforms()) {
11427                                                                        source.addTransform(transform);
11428                                                                }
11429                                                        }
11430                                                        if(sourceColumn.isPseduo()) {
11431                                                                source.setSource("system");
11432                                                        }
11433                                                        relationElement.addSource(source);
11434                                                }
11435                                        } else if (sourceElement instanceof TableColumn) {
11436                                                TableColumn sourceColumn = (TableColumn) sourceElement;
11437                                                if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()
11438                                                                && sourceItem instanceof TableColumnRelationshipElement) {
11439                                                        sourceColumn source = new sourceColumn();
11440                                                        boolean find = false;
11441                                                        if (((TableColumnRelationshipElement) sourceItem).getColumnIndex() != null) {
11442                                                                int columnIndex = ((TableColumnRelationshipElement) sourceItem).getColumnIndex();
11443                                                                if (sourceColumn.getStarLinkColumns().size() > columnIndex) {
11444                                                                        source = new sourceColumn();
11445                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + columnIndex);
11446                                                                        String targetObjectName = getColumnName(
11447                                                                                        sourceColumn.getStarLinkColumnList().get(columnIndex));
11448                                                                        source.setColumn(targetObjectName);
11449                                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11450                                                                        source.setParent_name(sourceColumn.getTable().getName());
11451                                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
11452                                                                                source.setParent_alias(
11453                                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11454                                                                        }
11455                                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11456                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11457                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11458                                                                        }
11459                                                                        append = true;
11460                                                                        relationElement.addSource(source);
11461                                                                        find = true;
11462                                                                }
11463                                                        }
11464
11465                                                        if (!find) {
11466                                                                String objectName = getColumnName(targetName);
11467
11468                                                                table tableElement = null;
11469                                                                if (dataflow.getTables() != null) {
11470                                                                        for (table t : dataflow.getTables()) {
11471                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
11472                                                                                        tableElement = t;
11473                                                                                        break;
11474                                                                                }
11475                                                                        }
11476                                                                }
11477                                                                if (tableElement == null && dataflow.getViews() != null) {
11478                                                                        for (table t : dataflow.getViews()) {
11479                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
11480                                                                                        tableElement = t;
11481                                                                                        break;
11482                                                                                }
11483                                                                        }
11484                                                                }
11485                                                                if (tableElement == null && dataflow.getVariables() != null) {
11486                                                                        for (table t : dataflow.getVariables()) {
11487                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
11488                                                                                        tableElement = t;
11489                                                                                        break;
11490                                                                                }
11491                                                                        }
11492                                                                }
11493
11494                                                                if(tableElement!=null) {
11495                                                                        for (column column : tableElement.getColumns()) {
11496                                                                                if (column.getName().equalsIgnoreCase(objectName)) {
11497                                                                                        source = new sourceColumn();
11498                                                                                        source.setId(String.valueOf(column.getId()));
11499                                                                                        source.setColumn(objectName);
11500                                                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11501                                                                                        source.setParent_name(sourceColumn.getTable().getName());
11502                                                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
11503                                                                                                source.setParent_alias(
11504                                                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11505                                                                                        }
11506                                                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11507                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11508                                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11509                                                                                        }
11510                                                                                        if (sourceItem.getTransforms() != null) {
11511                                                                                                for (Transform transform : sourceItem.getTransforms()) {
11512                                                                                                        source.addTransform(transform);
11513                                                                                                }
11514                                                                                        }
11515                                                                                        if (sourceColumn.getCandidateParents() != null) {
11516                                                                                                for(Object item: sourceColumn.getCandidateParents()) {
11517                                                                                                        candidateTable candidateParent = new candidateTable();
11518                                                                                                        if(item instanceof Table) {
11519                                                                                                                candidateParent.setId(String.valueOf(((Table)item).getId()));
11520                                                                                                                candidateParent.setName(getTableName((Table)item));
11521                                                                                                                source.addCandidateParent(candidateParent);
11522                                                                                                        }
11523                                                                                                        else if(item instanceof ResultSet) {
11524                                                                                                                candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
11525                                                                                                                candidateParent.setName(getResultSetName((ResultSet)item));
11526                                                                                                                source.addCandidateParent(candidateParent);
11527                                                                                                        }
11528                                                                                                }
11529                                                                                        }
11530                                                                                        append = true;
11531                                                                                        relationElement.addSource(source);
11532                                                                                        find = true;
11533                                                                                        break;
11534                                                                                }
11535                                                                        }
11536                                                                }
11537                                                        }
11538
11539                                                        if(!find) {
11540                                                                source = new sourceColumn();
11541                                                                source.setId(String.valueOf(sourceColumn.getId()));
11542                                                                source.setColumn(sourceColumn.getName());
11543                                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11544                                                                source.setParent_name(sourceColumn.getTable().getName());
11545                                                                if (sourceItem instanceof TableColumnRelationshipElement) {
11546                                                                        source.setParent_alias(
11547                                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11548                                                                }
11549                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11550                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11551                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11552                                                                }
11553                                                                if (sourceItem.getTransforms() != null) {
11554                                                                        for (Transform transform : sourceItem.getTransforms()) {
11555                                                                                source.addTransform(transform);
11556                                                                        }
11557                                                                }
11558                                                                if (sourceColumn.getCandidateParents() != null) {
11559                                                                        for(Object item: sourceColumn.getCandidateParents()) {
11560                                                                                candidateTable candidateParent = new candidateTable();
11561                                                                                if(item instanceof Table) {
11562                                                                                        candidateParent.setId(String.valueOf(((Table)item).getId()));
11563                                                                                        candidateParent.setName(getTableName((Table)item));
11564                                                                                        source.addCandidateParent(candidateParent);
11565                                                                                }
11566                                                                                else if(item instanceof ResultSet) {
11567                                                                                        candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
11568                                                                                        candidateParent.setName(getResultSetName((ResultSet)item));
11569                                                                                        source.addCandidateParent(candidateParent);
11570                                                                                }
11571                                                                        }
11572                                                                }
11573                                                                append = true;
11574                                                                relationElement.addSource(source);
11575                                                        }
11576
11577                                                } else {
11578                                                        sourceColumn source = new sourceColumn();
11579                                                        source.setId(String.valueOf(sourceColumn.getId()));
11580                                                        source.setColumn(sourceColumn.getName());
11581                                                        source.setStruct(sourceColumn.isStruct());
11582                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11583                                                        source.setParent_name(getTableName(sourceColumn.getTable()));
11584                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
11585                                                                source.setParent_alias(
11586                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11587                                                        }
11588                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11589                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11590                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11591                                                        }
11592                                                        if (sourceItem.getTransforms() != null) {
11593                                                                for (Transform transform : sourceItem.getTransforms()) {
11594                                                                        source.addTransform(transform);
11595                                                                }
11596                                                        }
11597                                                        if(sourceColumn.isPseduo()) {
11598                                                                source.setSource("system");
11599                                                        }
11600                                                        if (sourceColumn.getCandidateParents() != null) {
11601                                                                for(Object item: sourceColumn.getCandidateParents()) {
11602                                                                        candidateTable candidateParent = new candidateTable();
11603                                                                        if(item instanceof Table) {
11604                                                                                candidateParent.setId(String.valueOf(((Table)item).getId()));
11605                                                                                candidateParent.setName(getTableName((Table)item));
11606                                                                                source.addCandidateParent(candidateParent);
11607                                                                        }
11608                                                                        else if(item instanceof ResultSet) {
11609                                                                                candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
11610                                                                                candidateParent.setName(getResultSetName((ResultSet)item));
11611                                                                                source.addCandidateParent(candidateParent);
11612                                                                        }
11613                                                                }
11614                                                        }
11615                                                        append = true;
11616                                                        relationElement.addSource(source);
11617                                                }
11618                                        } else if (sourceElement instanceof Argument) {
11619                                                Argument sourceColumn = (Argument) sourceElement;
11620                                                sourceColumn source = new sourceColumn();
11621                                                source.setId(String.valueOf(sourceColumn.getId()));
11622                                                source.setColumn(sourceColumn.getName());
11623                                                source.setParent_id(String.valueOf(sourceColumn.getProcedure().getId()));
11624                                                source.setParent_name(sourceColumn.getProcedure().getName());
11625                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11626                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11627                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11628                                                }
11629                                                append = true;
11630                                                relationElement.addSource(source);
11631                                        } else if (sourceElement instanceof TableRelationRows) {
11632                                                TableRelationRows sourceColumn = (TableRelationRows) sourceElement;
11633                                                sourceColumn source = new sourceColumn();
11634                                                source.setId(String.valueOf(sourceColumn.getId()));
11635                                                source.setColumn(sourceColumn.getName());
11636                                                source.setParent_id(String.valueOf(sourceColumn.getHolder().getId()));
11637                                                source.setParent_name(getTableName(sourceColumn.getHolder()));
11638                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11639                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11640                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11641                                                }
11642                                                source.setSource("system");
11643                                                append = true;
11644                                                relationElement.addSource(source);
11645                                        } else if (sourceElement instanceof ResultSetRelationRows) {
11646                                                ResultSetRelationRows sourceColumn = (ResultSetRelationRows) sourceElement;
11647                                                sourceColumn source = new sourceColumn();
11648                                                source.setId(String.valueOf(sourceColumn.getId()));
11649                                                source.setColumn(sourceColumn.getName());
11650                                                source.setParent_id(String.valueOf(sourceColumn.getHolder().getId()));
11651                                                source.setParent_name(getResultSetName(sourceColumn.getHolder()));
11652                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11653                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11654                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11655                                                }
11656                                                source.setSource("system");
11657                                                append = true;
11658                                                relationElement.addSource(source);
11659                                        } else if (sourceElement instanceof Constant) {
11660                                                Constant sourceColumn = (Constant) sourceElement;
11661                                                sourceColumn source = new sourceColumn();
11662                                                source.setId(String.valueOf(sourceColumn.getId()));
11663                                                source.setColumn(sourceColumn.getName());
11664                                                source.setColumn_type("constant");
11665                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11666                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11667                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11668                                                }
11669                                                append = true;
11670                                                relationElement.addSource(source);
11671                                        } else if (sourceElement instanceof Table) {
11672                                                Table table = (Table) sourceElement;
11673                                                sourceColumn source = new sourceColumn();
11674                                                source.setSource_id(String.valueOf(table.getId()));
11675                                                source.setSource_name(getTableName(table));
11676                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
11677                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
11678                                                                        + convertCoordinate(table.getEndPosition()));
11679                                                }
11680                                                append = true;
11681                                                relationElement.addSource(source);
11682                                        }
11683
11684                                        if (relation instanceof ImpactRelationship) {
11685                                                ESqlClause clause = getSqlClause(sourceItem);
11686                                                if (clause != null
11687                                                                && (relationElement.getSources() != null && !relationElement.getSources().isEmpty())) {
11688                                                        relationElement.getSources().get(relationElement.getSources().size() - 1)
11689                                                                        .setClauseType(clause.name());
11690                                                }
11691                                        }
11692                                }
11693                                if (append)
11694                                        dataflow.getRelationships().add(relationElement);
11695                        }
11696                }
11697        }
11698
11699        private boolean containsStar(Collection<RelationshipElement<?>> elements) {
11700                if (elements == null || elements.size() == 0)
11701                        return false;
11702
11703                for (RelationshipElement<?> element : elements) {
11704                        if (element.getElement() instanceof ResultColumn) {
11705                                ResultColumn object = (ResultColumn) element.getElement();
11706                                if (object.getName().endsWith("*") && object.isShowStar())
11707                                        return true;
11708                        } else if (element.getElement() instanceof TableColumn) {
11709                                TableColumn object = (TableColumn) element.getElement();
11710                                if (object.getName().endsWith("*") && object.isShowStar())
11711                                        return true;
11712                        }
11713                }
11714                return false;
11715        }
11716
11717        private Map<String, Set<String>> appendTableStarColumns = new HashMap<String, Set<String>>();
11718        private void updateResultColumnStarLinks(dataflow dataflow, AbstractRelationship relation, int index) {
11719                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
11720                        return;
11721                }
11722                
11723                ResultColumn targetColumn = (ResultColumn) relation.getTarget().getElement();
11724                
11725                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
11726                if (sourceElements == null || sourceElements.size() == 0)
11727                        return;
11728
11729                for (RelationshipElement<?> sourceItem: sourceElements) {
11730                        Object sourceElement = sourceItem.getElement();
11731                        if (sourceElement instanceof ResultColumn) {
11732                                ResultColumn source = (ResultColumn) sourceElement;
11733                                if (source.hasStarLinkColumn()) {
11734                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11735                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11736                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11737                                                }
11738                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11739                                        }
11740                                        if (!source.isShowStar()) {
11741                                                targetColumn.setShowStar(false);
11742                                                relation.setShowStarRelation(false);
11743                                        }
11744                                } else if (!"*".equals(source.getName())) {
11745                                        if (source.getColumnObject() instanceof TObjectName) {
11746                                                if (source instanceof FunctionResultColumn) {
11747
11748                                                } else {
11749                                                        targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject());
11750                                                }
11751                                        } else if (source.getColumnObject() instanceof TResultColumn) {
11752                                                TResultColumn sourceColumn = (TResultColumn) source.getColumnObject();
11753                                                if (sourceColumn.getAliasClause() != null) {
11754                                                        targetColumn.bindStarLinkColumn(sourceColumn.getAliasClause().getAliasName());
11755                                                } else if (sourceColumn.getFieldAttr() != null) {
11756                                                        targetColumn.bindStarLinkColumn(sourceColumn.getFieldAttr());
11757                                                } else {
11758                                                        TObjectName column = new TObjectName();
11759                                                        if (sourceColumn.getExpr().getExpressionType() == EExpressionType.typecast_t) {
11760                                                                column.setString(sourceColumn.getExpr().getLeftOperand().toString());
11761                                                        } else {
11762                                                                column.setString(sourceColumn.toString());
11763                                                        }
11764                                                        targetColumn.bindStarLinkColumn(column);
11765                                                }
11766                                        }
11767                                }
11768                        } else if (sourceElement instanceof TableColumn) {
11769                                TableColumn source = (TableColumn) sourceElement;
11770                                if (!source.isPseduo() && source.hasStarLinkColumn()) {
11771                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11772                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11773                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11774                                                }
11775                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11776                                        }
11777                                        if ((source.getTable().isCreateTable() || source.getTable().hasSQLEnv()) && !source.isShowStar()) {
11778                                                targetColumn.setShowStar(false);
11779                                                relation.setShowStarRelation(false);
11780                                        }
11781
11782                                } else if (!"*".equals(source.getName())) {
11783                                        targetColumn.bindStarLinkColumn(source.getColumnObject());
11784                                }
11785                        }
11786                }
11787
11788                if (targetColumn.hasStarLinkColumn()) {
11789                        table resultSetElement = null;
11790                        for (table t : dataflow.getResultsets()) {
11791                                if (t.getId().equals(String.valueOf(targetColumn.getResultSet().getId()))) {
11792                                        resultSetElement = t;
11793                                        break;
11794                                }
11795                        }
11796                        
11797                        int starColumnCount = 0;
11798                        for(column item: resultSetElement.getColumns()) {
11799                                if(item.getName().endsWith("*")) {
11800                                        starColumnCount+=1;
11801                                }
11802                        }
11803                        
11804                        if (resultSetElement != null && starColumnCount <= 1) {
11805                                List<String> columns = targetColumn.getStarLinkColumnNames();
11806                                if (index == -1) {
11807                                        for (int k = 0; k < columns.size(); k++) {
11808                                                String columnName = columns.get(k);
11809                                                String id = String.valueOf(targetColumn.getId()) + "_" + k;
11810                                                if(appendTableStarColumns.containsKey(resultSetElement.getId()) && appendTableStarColumns.get(resultSetElement.getId()).contains(id)) {
11811                                                        continue;
11812                                                }
11813                                                column columnElement = new column();
11814                                                columnElement.setId(id);
11815                                                columnElement.setName(columnName);
11816                                                if (targetColumn.isFunction()) {
11817                                                        columnElement.setIsFunction(String.valueOf(targetColumn.isFunction()));
11818                                                }
11819                                                if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11820                                                        columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11821                                                                        + convertCoordinate(targetColumn.getEndPosition()));
11822                                                }
11823
11824                                                if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) {
11825                                                        boolean find = false;
11826                                                        for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
11827                                                                ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
11828                                                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName())
11829                                                                                .equals(columnName)) {
11830                                                                        find = true;
11831                                                                        break;
11832                                                                }
11833                                                        }
11834                                                        if (find) {
11835                                                                continue;
11836                                                        }
11837                                                }
11838                                                
11839                                                if (!resultSetElement.getColumns().contains(columnElement)) {
11840                                                        resultSetElement.getColumns().add(columnElement);
11841                                                        appendTableStarColumns.putIfAbsent(resultSetElement.getId(), new HashSet<String>());
11842                                                        appendTableStarColumns.get(resultSetElement.getId()).add(id);
11843                                                }
11844                                        }
11845                                }
11846                                else {
11847                                        int k = index;
11848                                        String columnName = columns.get(k);
11849                                        column columnElement = new column();
11850                                        columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k);
11851                                        columnElement.setName(columnName);
11852                                        if (targetColumn.isFunction()) {
11853                                                columnElement.setIsFunction(String.valueOf(targetColumn.isFunction()));
11854                                        }
11855                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11856                                                columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11857                                                                + convertCoordinate(targetColumn.getEndPosition()));
11858                                        }
11859
11860                                        if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) {
11861                                                boolean find = false;
11862                                                for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
11863                                                        ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
11864                                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
11865                                                                find = true;
11866                                                                break;
11867                                                        }
11868                                                }
11869                                                if (find) {
11870                                                        return;
11871                                                }
11872                                        }
11873
11874                                        if (!resultSetElement.getColumns().contains(columnElement)) {
11875                                                resultSetElement.getColumns().add(columnElement);
11876                                        }
11877                                }
11878                        }
11879                }
11880        }
11881
11882        private void updateTableColumnStarLinks(dataflow dataflow, AbstractRelationship relation) {
11883                TableColumn targetColumn = (TableColumn) relation.getTarget().getElement();             
11884                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
11885                if (sourceElements == null || sourceElements.size() == 0)
11886                        return;
11887
11888                TableColumn sourceStarColumn = null;
11889
11890                for (RelationshipElement<?> sourceItem: sourceElements) {
11891                        Object sourceElement = sourceItem.getElement();
11892                        if (sourceElement instanceof ResultColumn) {
11893                                ResultColumn source = (ResultColumn) sourceElement;
11894                                if(source.getResultSet() instanceof Function) {
11895                                        continue;
11896                                }
11897                                if (source.hasStarLinkColumn()) {
11898                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11899                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11900                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11901                                                }
11902                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11903                                        }
11904                                        if (!source.isShowStar()) {
11905                                                targetColumn.setShowStar(false);
11906                                                relation.setShowStarRelation(false);
11907                                        }
11908                                } else if (!"*".equals(source.getName())) {
11909                                        if (source.getColumnObject() instanceof TObjectName) {
11910                                                targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject());
11911                                        } else if (source.getColumnObject() instanceof TResultColumn) {
11912                                                if (((TResultColumn) source.getColumnObject()).getAliasClause() != null) {
11913                                                        TObjectName field = ((TResultColumn) source.getColumnObject()).getAliasClause()
11914                                                                        .getAliasName();
11915                                                        if (field != null) {
11916                                                                targetColumn.bindStarLinkColumn(field);
11917                                                        }
11918                                                } else {
11919                                                        TObjectName field = ((TResultColumn) source.getColumnObject()).getFieldAttr();
11920                                                        if (field != null) {
11921                                                                targetColumn.bindStarLinkColumn(field);
11922                                                        } else {
11923                                                                TObjectName column = new TObjectName();
11924                                                                if (((TResultColumn) source.getColumnObject()).getExpr()
11925                                                                                .getExpressionType() == EExpressionType.typecast_t) {
11926                                                                        column.setString(((TResultColumn) source.getColumnObject()).getExpr()
11927                                                                                        .getLeftOperand().toString());
11928                                                                } else {
11929                                                                        column.setString(((TResultColumn) source.getColumnObject()).toString());
11930                                                                }
11931                                                                targetColumn.bindStarLinkColumn(column);
11932                                                        }
11933                                                }
11934                                        }
11935                                }
11936                        } else if (sourceElement instanceof TableColumn) {
11937                                TableColumn source = (TableColumn) sourceElement;
11938                                if (source.hasStarLinkColumn()) {
11939                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11940                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11941                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11942                                                }
11943                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11944                                        }
11945                                        for (Map.Entry<String, Set<TObjectName>> item : targetColumn.getStarLinkColumns().entrySet()) {
11946                                                if (!source.getStarLinkColumns().containsKey(item.getKey())) {
11947                                                        source.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11948                                                }
11949                                                source.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11950                                        }
11951
11952                                        sourceStarColumn = source;
11953
11954                                        if (source.getTable().isCreateTable() && !source.isShowStar()) {
11955                                                targetColumn.setShowStar(false);
11956                                                relation.setShowStarRelation(false);
11957                                        }
11958                                } else if (!"*".equals(source.getName())) {
11959                                        if (source.isStruct()) {
11960                                                targetColumn.bindStarLinkColumn(source.getColumnObject());
11961                                        }
11962                                        else {
11963                                                TObjectName objectName = new TObjectName();
11964                                                objectName.setString(DlineageUtil.getColumnNameOnly(source.getName()));
11965                                                targetColumn.bindStarLinkColumn(objectName);
11966                                        }
11967                                }
11968                        }
11969                }
11970
11971                if (targetColumn.hasStarLinkColumn()) {
11972                        table tableElement = null;
11973                        if (dataflow.getTables() != null) {
11974                                for (table t : dataflow.getTables()) {
11975                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
11976                                                tableElement = t;
11977                                                break;
11978                                        }
11979                                }
11980                        }
11981                        if (tableElement == null && dataflow.getViews() != null) {
11982                                for (table t : dataflow.getViews()) {
11983                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
11984                                                tableElement = t;
11985                                                break;
11986                                        }
11987                                }
11988                        }
11989                        if (tableElement == null && dataflow.getVariables() != null) {
11990                                for (table t : dataflow.getVariables()) {
11991                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
11992                                                tableElement = t;
11993                                                break;
11994                                        }
11995                                }
11996                        }
11997
11998                        if (tableElement != null) {
11999                                List<String> columns = new ArrayList<String>(targetColumn.getStarLinkColumns().keySet());
12000                                for (int k = 0; k < columns.size(); k++) {
12001                                        String columnName = columns.get(k);
12002                                        if (containStarColumn(targetColumn.getTable().getColumns(), columnName)) {
12003                                                continue;
12004                                        }
12005                                        column columnElement = new column();
12006                                        columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k);
12007                                        columnElement.setName(columnName);
12008                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12009                                                columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12010                                                                + convertCoordinate(targetColumn.getEndPosition()));
12011                                        }
12012                                        if (!tableElement.getColumns().contains(columnElement)) {
12013                                                tableElement.getColumns().add(columnElement);
12014                                        }
12015                                }
12016                        }
12017                }
12018
12019                if (sourceStarColumn != null) {
12020                        table tableElement = null;
12021                        if (dataflow.getTables() != null) {
12022                                for (table t : dataflow.getTables()) {
12023                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
12024                                                tableElement = t;
12025                                                break;
12026                                        }
12027                                }
12028                        }
12029                        if (tableElement == null && dataflow.getViews() != null) {
12030                                for (table t : dataflow.getViews()) {
12031                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
12032                                                tableElement = t;
12033                                                break;
12034                                        }
12035                                }
12036                        }
12037                        if (tableElement == null && dataflow.getVariables() != null) {
12038                                for (table t : dataflow.getVariables()) {
12039                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
12040                                                tableElement = t;
12041                                                break;
12042                                        }
12043                                }
12044                        }
12045
12046                        if (tableElement != null) {
12047                                List<String> columns = new ArrayList<String>(sourceStarColumn.getStarLinkColumns().keySet());
12048                                for (int k = 0; k < columns.size(); k++) {
12049                                        String columnName = columns.get(k);
12050                                        if (containStarColumn(sourceStarColumn.getTable().getColumns(), columnName)) {
12051                                                continue;
12052                                        }
12053                                        column columnElement = new column();
12054                                        columnElement.setId(sourceStarColumn.getId() + "_" + k);
12055                                        columnElement.setName(columnName);
12056                                        if (sourceStarColumn.getStartPosition() != null && sourceStarColumn.getEndPosition() != null) {
12057                                                columnElement.setCoordinate(convertCoordinate(sourceStarColumn.getStartPosition()) + ","
12058                                                                + convertCoordinate(sourceStarColumn.getEndPosition()));
12059                                        }
12060                                        if (!tableElement.getColumns().contains(columnElement)) {
12061                                                tableElement.getColumns().add(columnElement);
12062                                        }
12063                                }
12064                        }
12065                }
12066        }
12067
12068        private ESqlClause getSqlClause(RelationshipElement<?> relationshipElement) {
12069                if (relationshipElement instanceof TableColumnRelationshipElement) {
12070                        return ((TableColumnRelationshipElement) relationshipElement).getRelationLocation();
12071                } else if (relationshipElement instanceof ResultColumnRelationshipElement) {
12072                        return ((ResultColumnRelationshipElement) relationshipElement).getRelationLocation();
12073                }
12074                return null;
12075        }
12076
12077        private void appendStarRelation(dataflow dataflow, AbstractRelationship relation, int index) {
12078                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
12079                        return;
12080                }
12081                
12082                Object targetElement = relation.getTarget().getElement();
12083
12084                relationship relationElement = new relationship();
12085                relationElement.setType(relation.getRelationshipType().name());
12086                if (relation.getEffectType() != null) {
12087                        relationElement.setEffectType(relation.getEffectType().name());
12088                }
12089                relationElement.setSqlHash(relation.getSqlHash());
12090                relationElement.setSqlComment(relation.getSqlComment());
12091
12092                if (relation.getProcedureId() != null) {
12093                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12094                }
12095                relationElement.setId(String.valueOf(relation.getId()) + "_" + index);
12096                if (relation.getProcess() != null) {
12097                        relationElement.setProcessId(String.valueOf(relation.getProcess().getId()));
12098                        if (relation.getProcess().getGspObject() != null) {
12099                                relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name());
12100                        }
12101                }
12102                if (relation instanceof DataFlowRelationship) {
12103                        relationElement.setSqlHash(((DataFlowRelationship) relation).getSqlHash());
12104                        relationElement.setSqlComment(((DataFlowRelationship) relation).getSqlComment());
12105                
12106                        if (relation.getProcedureId() != null) {
12107                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12108                        }
12109                }
12110                String targetName = "";
12111
12112                if (targetElement instanceof ResultColumn) {
12113                        ResultColumn targetColumn = (ResultColumn) targetElement;
12114
12115                        targetName = targetColumn.getStarLinkColumnNames().get(index);
12116
12117                        
12118                        targetColumn target = new targetColumn();
12119                        target.setId(String.valueOf(targetColumn.getId()) + "_" + index);
12120                        if(targetColumn.getResultSet()!=null && targetColumn.getResultSet().getColumns()!=null) {
12121                                for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
12122                                        ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
12123                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(targetName)) {
12124                                                target.setId(String.valueOf(columnModel.getId()));
12125                                                break;
12126                                        }
12127                                }
12128                        }
12129                        target.setColumn(targetName);
12130                        target.setStruct(targetColumn.isStruct());
12131                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
12132                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
12133                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12134                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12135                                                + convertCoordinate(targetColumn.getEndPosition()));
12136                        }
12137                        relationElement.setTarget(target);
12138                } else if (targetElement instanceof TableColumn) {
12139                        TableColumn targetColumn = (TableColumn) targetElement;
12140
12141                        targetName = targetColumn.getStarLinkColumnNames().get(index);
12142
12143                        TableColumn tableColumn = searchTableColumn(targetColumn.getTable().getColumns(), targetName);
12144
12145                        targetColumn target = new targetColumn();
12146                        if (tableColumn == null) {
12147                                target.setId(targetColumn.getId() + "_" + index);
12148                        } else {
12149                                target.setId(String.valueOf(tableColumn.getId()));
12150                        }
12151                        target.setStruct(targetColumn.isStruct());
12152                        target.setColumn(targetName);
12153                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
12154                        target.setParent_name(targetColumn.getTable().getName());
12155                        if (relation.getTarget() instanceof TableColumnRelationshipElement) {
12156                                target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias());
12157                        }
12158                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12159                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12160                                                + convertCoordinate(targetColumn.getEndPosition()));
12161                        }
12162                        relationElement.setTarget(target);
12163                } else {
12164                        return;
12165                }
12166
12167                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
12168                if (sourceElements.size() == 0) {
12169                        return;
12170                }
12171
12172                String targetIdentifierName = DlineageUtil.getIdentifierNormalColumnName(targetName);
12173                if (targetIdentifierName == null) {
12174                        return;
12175                }
12176                for (RelationshipElement<?> sourceItem: sourceElements) {
12177                        Object sourceElement = sourceItem.getElement();
12178                        if (sourceElement instanceof ResultColumn) {
12179                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
12180                                if (sourceColumn.hasStarLinkColumn()) {
12181                                        List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames();
12182                                        int linkColumnNameSize = linkColumnNames.size();
12183                                        for (int k = 0; k < linkColumnNameSize; k++) {
12184                                                String sourceName = linkColumnNames.get(k);
12185                                                if (relation.getRelationshipType() == RelationshipType.fdd) {
12186                                                        if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName))
12187                                                                continue;
12188                                                }
12189                                                sourceColumn source = new sourceColumn();                                               
12190                                                
12191                                                boolean find = false;
12192                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
12193                                                        for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) {
12194                                                                ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i);
12195                                                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(sourceName)) {
12196                                                                        source.setId(String.valueOf(columnModel.getId()));
12197                                                                        find = true;
12198                                                                        break;
12199                                                                }
12200                                                        }
12201                                                }
12202                                                if(!find) {
12203                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + k);
12204                                                }
12205                                                source.setColumn(sourceName);
12206                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12207                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12208                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12209                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12210                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12211                                                }
12212                                                if (sourceItem.getTransforms() != null) {
12213                                                        for (Transform transform : sourceItem.getTransforms()) {
12214                                                                source.addTransform(transform);
12215                                                        }
12216                                                }
12217                                                relationElement.addSource(source);
12218                                        }
12219                                        if(relationElement.getSources().isEmpty() && sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
12220                                                for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) {
12221                                                        ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i);
12222                                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equalsIgnoreCase(targetIdentifierName)) {
12223                                                                sourceColumn source = new sourceColumn();
12224                                                                source.setId(String.valueOf(columnModel.getId()));
12225                                                                source.setColumn(columnModel.getName());
12226                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12227                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12228                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12229                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12230                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12231                                                                }
12232                                                                if (sourceItem.getTransforms() != null) {
12233                                                                        for (Transform transform : sourceItem.getTransforms()) {
12234                                                                                source.addTransform(transform);
12235                                                                        }
12236                                                                }
12237                                                                relationElement.addSource(source);
12238                                                                break;
12239                                                        }
12240                                                }
12241                                        }
12242                                        if (relationElement.getSources().isEmpty()) {
12243                                                TObjectName sourceStarLinkColumn = new TObjectName();
12244                                                sourceStarLinkColumn.setString(targetName);
12245                                                boolean newBinding = sourceColumn.bindStarLinkColumn(sourceStarLinkColumn);
12246                                                sourceColumn source = new sourceColumn();
12247                                                String sourceName = DlineageUtil.getColumnName(sourceStarLinkColumn);
12248                                                if (!newBinding) {
12249                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
12250                                                                        + sourceColumn.indexOfStarLinkColumn(sourceStarLinkColumn));
12251                                                } else {
12252                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize);
12253                                                }
12254                                                source.setColumn(sourceName);
12255                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12256                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12257                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12258                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12259                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12260                                                }
12261                                                if (sourceItem.getTransforms() != null) {
12262                                                        for (Transform transform : sourceItem.getTransforms()) {
12263                                                                source.addTransform(transform);
12264                                                        }
12265                                                }
12266                                                relationElement.addSource(source);
12267
12268                                                if (newBinding) {
12269                                                        table resultSetElement = null;
12270                                                        for (table t : dataflow.getResultsets()) {
12271                                                                if (t.getId().equals(String.valueOf(sourceColumn.getResultSet().getId()))) {
12272                                                                        resultSetElement = t;
12273                                                                        break;
12274                                                                }
12275                                                        }
12276                                                        if (resultSetElement != null) {
12277                                                                column columnElement = new column();
12278                                                                columnElement.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize);
12279                                                                columnElement.setName(sourceName);
12280                                                                if (sourceColumn.isFunction()) {
12281                                                                        columnElement.setIsFunction(String.valueOf(sourceColumn.isFunction()));
12282                                                                }
12283                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12284                                                                        columnElement.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12285                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12286                                                                }
12287                                                                resultSetElement.getColumns().add(columnElement);
12288                                                        }
12289                                                }
12290                                        }
12291                                } else {
12292                                        sourceColumn source = new sourceColumn();
12293                                        source.setId(String.valueOf(sourceColumn.getId()));
12294                                        source.setColumn(sourceColumn.getName());
12295                                        source.setStruct(sourceColumn.isStruct());
12296                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12297                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12298                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12299                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12300                                                                + convertCoordinate(sourceColumn.getEndPosition()));
12301                                        }
12302                                        if (relation.getRelationshipType() == RelationshipType.fdd) {
12303                                                if (!targetIdentifierName
12304                                                                .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))) {
12305                                                        if (!"*".equals(sourceColumn.getName())) {
12306                                                                continue;
12307                                                        }
12308                                                        else {
12309                                                                boolean flag = false;
12310                                                                for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
12311                                                                        if(targetIdentifierName
12312                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
12313                                                                                flag = true;
12314                                                                                break;
12315                                                                        }
12316                                                                }
12317                                                                if(flag) {
12318                                                                        continue;
12319                                                                }
12320                                                        }
12321                                                }
12322                                        }
12323                                        if (sourceItem.getTransforms() != null) {
12324                                                for (Transform transform : sourceItem.getTransforms()) {
12325                                                        source.addTransform(transform);
12326                                                }
12327                                        }
12328                                        relationElement.addSource(source);
12329                                }
12330                        } else if (sourceElement instanceof TableColumn) {
12331                                TableColumn sourceColumn = (TableColumn) sourceElement;
12332                                if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()) {
12333                                        List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames();
12334                                        int linkColumnNameSize = linkColumnNames.size();
12335                                        for (int k = 0; k < linkColumnNameSize; k++) {
12336                                                String sourceName = linkColumnNames.get(k);
12337                                                if (relation.getRelationshipType() == RelationshipType.fdd) {
12338                                                        if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName))
12339                                                                continue;
12340                                                }
12341
12342                                                TableColumn tableColumn = searchTableColumn(sourceColumn.getTable().getColumns(), sourceName);
12343
12344                                                sourceColumn source = new sourceColumn();
12345                                                if (tableColumn == null) {
12346                                                        source.setId(sourceColumn.getId() + "_" + k);
12347                                                } else {
12348                                                        source.setId(String.valueOf(tableColumn.getId()));
12349                                                }
12350                                                source.setColumn(sourceName);
12351                                                source.setStruct(sourceColumn.isStruct());
12352                                                if (containStarColumn(sourceElements, sourceName)) {
12353                                                        continue;
12354                                                }
12355                                                if (sourceColumn.getTable().getColumns().size() > 1) {
12356                                                        for (int y = 0; y < sourceColumn.getTable().getColumns().size(); y++) {
12357                                                                if (sourceColumn.getTable().getColumns().get(y).getName()
12358                                                                                .equalsIgnoreCase(sourceName)) {
12359                                                                        source.setId(String.valueOf(sourceColumn.getTable().getColumns().get(y).getId()));
12360                                                                        break;
12361                                                                }
12362                                                        }
12363                                                }
12364                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
12365                                                source.setParent_name(getTableName(sourceColumn.getTable()));
12366                                                if (sourceItem instanceof TableColumnRelationshipElement) {
12367                                                        source.setParent_alias(
12368                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
12369                                                }
12370                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12371                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12372                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12373                                                }
12374                                                if (sourceItem.getTransforms() != null) {
12375                                                        for (Transform transform : sourceItem.getTransforms()) {
12376                                                                source.addTransform(transform);
12377                                                        }
12378                                                }
12379                                                relationElement.addSource(source);
12380                                        }
12381                                } else {
12382                                        sourceColumn source = new sourceColumn();
12383                                        source.setId(String.valueOf(sourceColumn.getId()));
12384                                        source.setColumn(sourceColumn.getName());
12385                                        source.setStruct(sourceColumn.isStruct());
12386                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
12387                                        source.setParent_name(getTableName(sourceColumn.getTable()));
12388                                        if (sourceItem instanceof TableColumnRelationshipElement) {
12389                                                source.setParent_alias(((TableColumnRelationshipElement) sourceItem).getTableAlias());
12390                                        }
12391                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12392                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12393                                                                + convertCoordinate(sourceColumn.getEndPosition()));
12394                                        }
12395                                        if (relation.getRelationshipType() == RelationshipType.fdd) {
12396                                                if (!targetIdentifierName
12397                                                                .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))
12398                                                                && !"*".equals(sourceColumn.getName()))
12399                                                        continue;
12400                                        }
12401                                        if (sourceItem.getTransforms() != null) {
12402                                                for (Transform transform : sourceItem.getTransforms()) {
12403                                                        source.addTransform(transform);
12404                                                }
12405                                        }
12406                                        relationElement.addSource(source);
12407                                }
12408                        }
12409                }
12410
12411                if (relationElement.getTarget() != null && relationElement.getSources() != null
12412                                && !relationElement.getSources().isEmpty()) {
12413                        dataflow.getRelationships().add(relationElement);
12414                }
12415        }
12416
12417        private String getColumnName(TObjectName column) {
12418                if (column == null) {
12419                        return null;
12420                }
12421                String name = column.getColumnNameOnly();
12422                if (name == null || "".equals(name.trim())) {
12423                        return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim());
12424                } else
12425                        return DlineageUtil.getIdentifierNormalColumnName(name.trim());
12426        }
12427
12428        private String getColumnName(String column) {
12429                if (column == null) {
12430                        return null;
12431                }
12432                String name = column.substring(column.lastIndexOf(".") + 1);
12433                if (name == null || "".equals(name.trim())) {
12434                        return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim());
12435                } else
12436                        return DlineageUtil.getIdentifierNormalColumnName(name.trim());
12437        }
12438        
12439        private String getColumnNameOnly(String column) {
12440                if (column == null) {
12441                        return null;
12442                }
12443                return DlineageUtil.getColumnNameOnly(column);
12444        }
12445
12446        private void appendRecordSetRelation(dataflow dataflow, Relationship[] relations) {
12447                for (int i = 0; i < relations.length; i++) {
12448                        AbstractRelationship relation = (AbstractRelationship) relations[i];
12449                        relationship relationElement = new relationship();
12450                        relationElement.setType(relation.getRelationshipType().name());
12451                        if (relation.getFunction() != null) {
12452                                relationElement.setFunction(relation.getFunction());
12453                        }
12454                        if (relation.getEffectType() != null) {
12455                                relationElement.setEffectType(relation.getEffectType().name());
12456                        }
12457                        relationElement.setSqlHash(relation.getSqlHash());
12458                        relationElement.setSqlComment(relation.getSqlComment());
12459
12460                        if (relation.getProcedureId() != null) {
12461                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12462                        }
12463                        relationElement.setId(String.valueOf(relation.getId()));
12464
12465                        if (relation instanceof RecordSetRelationship) {
12466                                RecordSetRelationship recordCountRelation = (RecordSetRelationship) relation;
12467
12468                                Object targetElement = recordCountRelation.getTarget().getElement();
12469                                if (targetElement instanceof ResultColumn) {
12470                                        ResultColumn targetColumn = (ResultColumn) targetElement;
12471                                        targetColumn target = new targetColumn();
12472                                        target.setId(String.valueOf(targetColumn.getId()));
12473                                        target.setColumn(targetColumn.getName());
12474                                        target.setStruct(targetColumn.isStruct());
12475                                        target.setFunction(recordCountRelation.getAggregateFunction());
12476                                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
12477                                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
12478                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12479                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12480                                                                + convertCoordinate(targetColumn.getEndPosition()));
12481                                        }
12482                                        relationElement.setTarget(target);
12483                                } else if (targetElement instanceof TableColumn) {
12484                                        TableColumn targetColumn = (TableColumn) targetElement;
12485                                        targetColumn target = new targetColumn();
12486                                        target.setId(String.valueOf(targetColumn.getId()));
12487                                        target.setColumn(targetColumn.getName());
12488                                        target.setStruct(targetColumn.isStruct());
12489                                        target.setFunction(recordCountRelation.getAggregateFunction());
12490                                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
12491                                        target.setParent_name(getTableName(targetColumn.getTable()));
12492                                        if (recordCountRelation.getTarget() instanceof TableColumnRelationshipElement) {
12493                                                target.setParent_alias(
12494                                                                ((TableColumnRelationshipElement) recordCountRelation.getTarget()).getTableAlias());
12495                                        }
12496                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12497                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12498                                                                + convertCoordinate(targetColumn.getEndPosition()));
12499                                        }
12500                                        relationElement.setTarget(target);
12501                                } else if (targetElement instanceof ResultSetRelationRows) {
12502                                        ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement;
12503                                        targetColumn target = new targetColumn();
12504                                        target.setId(String.valueOf(targetColumn.getId()));
12505                                        target.setColumn(targetColumn.getName());
12506                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
12507                                        target.setParent_name(getResultSetName(targetColumn.getHolder()));
12508                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12509                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12510                                                                + convertCoordinate(targetColumn.getEndPosition()));
12511                                        }
12512                                        target.setSource("system");
12513                                        relationElement.setTarget(target);
12514                                } else {
12515                                        continue;
12516                                }
12517
12518                                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)recordCountRelation.getSources();
12519                                if (sourceElements.size() == 0) {
12520                                        continue;
12521                                }
12522
12523                                boolean append = false;
12524                                for (RelationshipElement<?> sourceItem: sourceElements) {
12525                                        Object sourceElement = sourceItem.getElement();
12526                                        if (sourceElement instanceof Table) {
12527                                                Table table = (Table) sourceElement;
12528                                                sourceColumn source = new sourceColumn();
12529                                                source.setSource_id(String.valueOf(table.getId()));
12530                                                source.setSource_name(getTableName(table));
12531                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
12532                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
12533                                                                        + convertCoordinate(table.getEndPosition()));
12534                                                }
12535                                                append = true;
12536                                                relationElement.addSource(source);
12537                                        } else if (sourceElement instanceof QueryTable) {
12538                                                QueryTable table = (QueryTable) sourceElement;
12539                                                sourceColumn source = new sourceColumn();
12540                                                source.setSource_id(String.valueOf(table.getId()));
12541                                                source.setSource_name(getResultSetName(table));
12542                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
12543                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
12544                                                                        + convertCoordinate(table.getEndPosition()));
12545                                                }
12546                                                append = true;
12547                                                relationElement.addSource(source);
12548                                        } else if (sourceElement instanceof TableRelationRows) {
12549                                                TableRelationRows relationRows = (TableRelationRows) sourceElement;
12550                                                sourceColumn source = new sourceColumn();
12551                                                source.setId(String.valueOf(relationRows.getId()));
12552                                                source.setColumn(relationRows.getName());
12553                                                source.setParent_id(String.valueOf(relationRows.getHolder().getId()));
12554                                                source.setParent_name(getTableName(relationRows.getHolder()));
12555                                                if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12556                                                        source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12557                                                                        + convertCoordinate(relationRows.getEndPosition()));
12558                                                }
12559                                                source.setSource("system");
12560                                                append = true;
12561                                                relationElement.addSource(source);
12562                                        } else if (sourceElement instanceof ResultSetRelationRows) {
12563                                                ResultSetRelationRows relationRows = (ResultSetRelationRows) sourceElement;
12564                                                sourceColumn source = new sourceColumn();
12565                                                source.setId(String.valueOf(relationRows.getId()));
12566                                                source.setColumn(relationRows.getName());
12567                                                source.setParent_id(String.valueOf(relationRows.getHolder().getId()));
12568                                                source.setParent_name(getResultSetName(relationRows.getHolder()));
12569                                                if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12570                                                        source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12571                                                                        + convertCoordinate(relationRows.getEndPosition()));
12572                                                }
12573                                                source.setSource("system");
12574                                                append = true;
12575                                                relationElement.addSource(source);
12576                                        } else if (sourceElement instanceof TableColumn) {
12577                                                TableColumn sourceColumn = (TableColumn) sourceElement;
12578                                                sourceColumn source = new sourceColumn();
12579                                                source.setId(String.valueOf(sourceColumn.getId()));
12580                                                source.setColumn(sourceColumn.getName());
12581                                                source.setStruct(sourceColumn.isStruct());
12582                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
12583                                                source.setParent_name(getTableName(sourceColumn.getTable()));
12584                                                if (sourceItem instanceof TableColumnRelationshipElement) {
12585                                                        source.setParent_alias(
12586                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
12587                                                }
12588                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12589                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12590                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12591                                                }
12592                                                append = true;
12593                                                relationElement.addSource(source);
12594                                        }
12595                                        if (sourceElement instanceof ResultColumn) {
12596                                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
12597                                                sourceColumn source = new sourceColumn();
12598                                                source.setId(String.valueOf(sourceColumn.getId()));
12599                                                source.setColumn(sourceColumn.getName());
12600                                                source.setStruct(sourceColumn.isStruct());
12601                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12602                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12603                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12604                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12605                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12606                                                }
12607                                                append = true;
12608                                                relationElement.addSource(source);
12609                                        }
12610                                }
12611
12612                                if (append)
12613                                        dataflow.getRelationships().add(relationElement);
12614                        }
12615                }
12616        }
12617
12618        private void appendCallRelation(dataflow dataflow, Relationship[] relations) {
12619                for (int i = 0; i < relations.length; i++) {
12620                        AbstractRelationship relation = (AbstractRelationship) relations[i];
12621                        relationship relationElement = new relationship();
12622                        relationElement.setType(relation.getRelationshipType().name());
12623                        if (relation.getFunction() != null) {
12624                                relationElement.setFunction(relation.getFunction());
12625                        }
12626                        if (relation.getEffectType() != null) {
12627                                relationElement.setEffectType(relation.getEffectType().name());
12628                        }
12629                        relationElement.setSqlHash(relation.getSqlHash());
12630                        relationElement.setSqlComment(relation.getSqlComment());
12631                        
12632                        if (relation.getProcedureId() != null) {
12633                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12634                        }
12635                        relationElement.setId(String.valueOf(relation.getId()));
12636
12637                        if (relation instanceof CallRelationship) {
12638                                CallRelationship callRelation = (CallRelationship) relation;
12639                                
12640                                if (callRelation.getCallObject() != null) {
12641                                        relationElement.setCallStmt(callRelation.getCallObject().toString());
12642                                        if (callRelation.getStartPosition() != null && callRelation.getEndPosition() != null) {
12643                                                relationElement.setCallCoordinate(convertCoordinate(callRelation.getStartPosition()) + ","
12644                                                                + convertCoordinate(callRelation.getEndPosition()));
12645                                        }
12646                                }
12647                                
12648                                if (Boolean.TRUE.equals(callRelation.getBuiltIn())) {
12649                                        relationElement.setBuiltIn(true);
12650                                }
12651                                Object targetElement = callRelation.getTarget().getElement();
12652                                if (targetElement instanceof Procedure) {
12653                                        Procedure procedure = (Procedure) targetElement;
12654                                        targetColumn target = new targetColumn();
12655                                        target.setId(String.valueOf(procedure.getId()));
12656                                        target.setName(getProcedureName(procedure));
12657                                        if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) {
12658                                                target.setCoordinate(convertCoordinate(procedure.getStartPosition()) + ","
12659                                                                + convertCoordinate(procedure.getEndPosition()));
12660                                        }
12661                                        String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase();
12662                                        if (clazz.indexOf("function") != -1) {
12663                                                target.setType("function");
12664                                        } else if (clazz.indexOf("trigger") != -1) {
12665                                                target.setType("trigger");
12666                                        } else if (clazz.indexOf("macro") != -1) {
12667                                                target.setType("macro");
12668                                        } else {
12669                                                target.setType("procedure");
12670                                        }
12671                                        relationElement.setCaller(target);
12672                                } else {
12673                                        continue;
12674                                }
12675
12676                                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)callRelation.getSources();
12677                                if (sourceElements.size() == 0) {
12678                                        continue;
12679                                }
12680
12681                                boolean append = false;
12682                                for (RelationshipElement<?> sourceItem: sourceElements) {
12683                                        Object sourceElement = sourceItem.getElement();
12684                                        if (sourceElement instanceof Procedure) {
12685                                                Procedure procedure = (Procedure) sourceElement;
12686                                                sourceColumn source = new sourceColumn();
12687                                                source.setId(String.valueOf(procedure.getId()));
12688                                                source.setName(getProcedureName(procedure));
12689                                                if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) {
12690                                                        source.setCoordinate(convertCoordinate(procedure.getStartPosition()) + ","
12691                                                                        + convertCoordinate(procedure.getEndPosition()));
12692                                                }
12693                                                String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase();
12694                                                if (clazz.indexOf("function") != -1) {
12695                                                        source.setType("function");
12696                                                } else if (clazz.indexOf("trigger") != -1) {
12697                                                        source.setType("trigger");
12698                                                } else if (clazz.indexOf("macro") != -1) {
12699                                                        source.setType("macro");
12700                                                } else {
12701                                                        source.setType("procedure");
12702                                                }
12703                                                append = true;
12704                                                relationElement.getCallees().add(source);
12705                                        } else if (sourceElement instanceof Function) {
12706                                                Function function = (Function) sourceElement;
12707                                                sourceColumn source = new sourceColumn();
12708                                                source.setId(String.valueOf(function.getId()));
12709                                                source.setName(getFunctionName(function.getFunctionObject()));
12710                                                if (function.getStartPosition() != null && function.getEndPosition() != null) {
12711                                                        source.setCoordinate(convertCoordinate(function.getStartPosition()) + ","
12712                                                                        + convertCoordinate(function.getEndPosition()));
12713                                                }
12714                                                source.setType("function");
12715                                                append = true;
12716                                                relationElement.getCallees().add(source);
12717                                        }
12718                                }
12719
12720                                if (append)
12721                                        dataflow.getRelationships().add(relationElement);
12722                        }
12723                }
12724        }
12725
12726        private void appendResultSets(dataflow dataflow) {
12727                Set<ResultSet> resultSets = modelManager.getResultSets(); 
12728                for (ResultSet resultSet: resultSets) {
12729                        appendResultSet(dataflow, resultSet);
12730                }
12731        }
12732
12733        private void appendResultSet(dataflow dataflow, ResultSet resultSetModel) {
12734                if (!appendResultSets.contains(resultSetModel)) {
12735                        appendResultSets.add(resultSetModel);
12736                } else {
12737                        return;
12738                }
12739
12740                table resultSetElement = new table();
12741                resultSetElement.setId(String.valueOf(resultSetModel.getId()));
12742                resultSetElement.setServer(resultSetModel.getServer());
12743                if (!SQLUtil.isEmpty(resultSetModel.getDatabase())) {
12744                        resultSetElement.setDatabase(resultSetModel.getDatabase());
12745                }
12746                if (!SQLUtil.isEmpty(resultSetModel.getSchema())) {
12747                        resultSetElement.setSchema(resultSetModel.getSchema());
12748                }
12749                resultSetElement.setName(getResultSetName(resultSetModel));
12750                resultSetElement.setType(getResultSetType(resultSetModel));
12751                // if ((ignoreRecordSet || simpleOutput) && resultSetModel.isTarget()) {
12752                resultSetElement.setIsTarget(String.valueOf(resultSetModel.isTarget()));
12753                // }
12754                resultSetElement.setIsDetermined(String.valueOf(resultSetModel.isDetermined()));
12755                if (resultSetModel.getStartPosition() != null && resultSetModel.getEndPosition() != null) {
12756                        resultSetElement.setCoordinate(convertCoordinate(resultSetModel.getStartPosition()) + ","
12757                                        + convertCoordinate(resultSetModel.getEndPosition()));
12758                }
12759                dataflow.getResultsets().add(resultSetElement);
12760
12761                List<ResultColumn> columns = resultSetModel.getColumns();
12762
12763                Map<String, Integer> columnCounts = new HashMap<String, Integer>();
12764                for (ResultColumn column : columns) {
12765                        String columnName = DlineageUtil.getIdentifierNormalColumnName(column.getName());
12766                        if (!columnCounts.containsKey(columnName)) {
12767                                columnCounts.put(columnName, 0);
12768                        }
12769                        columnCounts.put(columnName, columnCounts.get(columnName) + 1);
12770                        // if (column.hasStarLinkColumn()) {
12771                        // List<String> starLinkColumns = column.getStarLinkColumnNames();
12772                        // for (int k = 0; k < starLinkColumns.size(); k++) {
12773                        // columnName = starLinkColumns.get(k);
12774                        // if (!columnCounts.containsKey(columnName)) {
12775                        // columnCounts.put(columnName, 0);
12776                        // }
12777                        // columnCounts.put(columnName, columnCounts.get(columnName) + 1);
12778                        // }
12779                        // }
12780                }
12781
12782                for (int j = 0; j < columns.size(); j++) {
12783                        ResultColumn columnModel = columns.get(j);
12784                        if (columnModel.hasStarLinkColumn()) {
12785                                // List<String> starLinkColumns =
12786                                // columnModel.getStarLinkColumnNames();
12787                                // for (int k = 0; k < starLinkColumns.size(); k++) {
12788                                // column columnElement = new column();
12789                                // columnElement.setId( String.valueOf(columnModel.getId()) +
12790                                // "_" + k);
12791                                // String columnName = starLinkColumns.get(k);
12792                                // columnElement.setName(columnName);
12793                                // if(columnModel.isFunction()){
12794                                // columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
12795                                // }
12796                                // if (columnModel.getStartPosition() != null &&
12797                                // columnModel.getEndPosition() != null) {
12798                                // columnElement.setCoordinate(
12799                                // columnModel.getStartPosition() + "," +
12800                                // columnModel.getEndPosition());
12801                                // }
12802                                // String identifier = columnName;
12803                                // if(columnCounts.containsKey(identifier) &&
12804                                // columnCounts.get(identifier)>1){
12805                                // TObjectName column =
12806                                // columnModel.getStarLinkColumns().get(columnName).iterator().next();
12807                                // if(!SQLUtil.isEmpty(getQualifiedTable(column))){
12808                                // columnElement.setQualifiedTable(getQualifiedTable(column));
12809                                // }
12810                                // }
12811                                // resultSetElement.getColumns().add(columnElement);
12812                                // }
12813                                if (columnModel.isShowStar()) {
12814                                        column columnElement = new column();
12815                                        columnElement.setId(String.valueOf(columnModel.getId()));
12816                                        columnElement.setName(columnModel.getName());
12817                                        if (columnModel.isFunction()) {
12818                                                columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
12819                                        }
12820                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
12821                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12822                                                                + convertCoordinate(columnModel.getEndPosition()));
12823                                        }
12824
12825                                        String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName());
12826                                        if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) {
12827                                                String qualifiedTable = getQualifiedTable(columnModel);
12828                                                if (!SQLUtil.isEmpty(qualifiedTable)) {
12829                                                        columnElement.setQualifiedTable(qualifiedTable);
12830                                                }
12831                                        }
12832                                        resultSetElement.getColumns().add(columnElement);
12833                                }
12834                        } else {
12835                                column columnElement = new column();
12836                                columnElement.setId(String.valueOf(columnModel.getId()));
12837                                columnElement.setName(columnModel.getName());
12838                                if (columnModel.isFunction()) {
12839                                        columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
12840                                }
12841                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
12842                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12843                                                        + convertCoordinate(columnModel.getEndPosition()));
12844                                }
12845
12846                                String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName());
12847                                if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) {
12848                                        String qualifiedTable = getQualifiedTable(columnModel);
12849                                        if (!SQLUtil.isEmpty(qualifiedTable)) {
12850                                                columnElement.setQualifiedTable(qualifiedTable);
12851                                        }
12852                                }
12853                                resultSetElement.getColumns().add(columnElement);
12854                        }
12855                }
12856
12857                ResultSetRelationRows relationRows = resultSetModel.getRelationRows();
12858                if (relationRows.hasRelation()) {
12859                        column relationRowsElement = new column();
12860                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12861                        relationRowsElement.setName(relationRows.getName());
12862                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12863                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12864                                                + convertCoordinate(relationRows.getEndPosition()));
12865                        }
12866                        relationRowsElement.setSource("system");
12867                        resultSetElement.getColumns().add(relationRowsElement);
12868                }
12869        }
12870
12871        private String getQualifiedTable(ResultColumn columnModel) {
12872                if (columnModel.getColumnObject() instanceof TObjectName) {
12873                        return getQualifiedTable((TObjectName) columnModel.getColumnObject());
12874                }
12875                if (columnModel.getColumnObject() instanceof TResultColumn) {
12876                        TObjectName field = ((TResultColumn) columnModel.getColumnObject()).getFieldAttr();
12877                        if (field != null) {
12878                                return getQualifiedTable(field);
12879                        }
12880                }
12881                return null;
12882        }
12883
12884        private String getQualifiedTable(TObjectName column) {
12885                if (column == null)
12886                        return null;
12887                String[] splits = column.toString().split("\\.");
12888                if (splits.length > 1) {
12889                        return splits[splits.length - 2];
12890                }
12891                return null;
12892        }
12893
12894        /**
12895         * Get the qualified prefix (schema.table) from a column name for 3-part names.
12896         * For example, for "sch.pk_constv2.c_cdsl", returns "sch.pk_constv2".
12897         * Returns null if the column doesn't have both schema and table parts.
12898         */
12899        private String getQualifiedPrefixFromColumn(TObjectName column) {
12900                if (column == null) return null;
12901
12902                // Check if both schema and table tokens are present (3-part name)
12903                String schemaStr = column.getSchemaString();
12904                String tableStr = column.getTableString();
12905
12906                if (schemaStr != null && !schemaStr.isEmpty() &&
12907                        tableStr != null && !tableStr.isEmpty()) {
12908                        return schemaStr + "." + tableStr;
12909                }
12910
12911                // Fallback: parse from toString() for complex cases
12912                String[] splits = column.toString().split("\\.");
12913                if (splits.length >= 3) {
12914                        // Return all parts except the last one (column name)
12915                        StringBuilder prefix = new StringBuilder();
12916                        for (int i = 0; i < splits.length - 1; i++) {
12917                                if (i > 0) prefix.append(".");
12918                                prefix.append(splits[i]);
12919                        }
12920                        return prefix.toString();
12921                }
12922
12923                return null;
12924        }
12925
12926        private String getResultSetType(ResultSet resultSetModel) {
12927                if (resultSetModel instanceof QueryTable) {
12928                        QueryTable table = (QueryTable) resultSetModel;
12929                        if (table.getTableObject().getCTE() != null) {
12930                                return "with_cte";
12931                        }
12932                }
12933
12934                if (resultSetModel instanceof SelectSetResultSet) {
12935                        ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType();
12936                        return "select_" + type.name();
12937                }
12938
12939                if (resultSetModel instanceof SelectResultSet) {
12940                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) {
12941                                return "insert-select";
12942                        }
12943                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) {
12944                                return "update-select";
12945                        }
12946                }
12947
12948                if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) {
12949                        return "merge-update";
12950                }
12951
12952                if (resultSetModel.getGspObject() instanceof TOutputClause) {
12953                        return ResultSetType.output.name();
12954                }
12955
12956                if (resultSetModel.getGspObject() instanceof TMergeInsertClause) {
12957                        return "merge-insert";
12958                }
12959
12960                if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) {
12961                        return "update-set";
12962                }
12963
12964                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) {
12965                        return ResultSetType.array.name();
12966                }
12967
12968                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) {
12969                        return ResultSetType.struct.name();
12970                }
12971
12972                if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) {
12973                        return ResultSetType.function.name();
12974                }
12975
12976                if (resultSetModel.getGspObject() instanceof TAliasClause) {
12977                        return ResultSetType.alias.name();
12978                }
12979
12980                if (resultSetModel.getGspObject() instanceof TCursorDeclStmt) {
12981                        return ResultSetType.cursor.name();
12982                }
12983
12984                if (resultSetModel instanceof PivotedTable) {
12985                        if (((PivotedTable) resultSetModel).isUnpivoted()) {
12986                                return ResultSetType.unpivot_table.name();
12987                        }
12988                        return ResultSetType.pivot_table.name();
12989                }
12990
12991                return "select_list";
12992        }
12993
12994        private String getTableName(Table tableModel) {
12995                if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) {
12996                        return modelManager.DISPLAY_NAME.get(tableModel.getId());
12997                }
12998
12999                String tableName;
13000                if (tableModel.getFullName() != null && tableModel.getFullName().trim().length() > 0) {
13001                        return tableModel.getFullName();
13002                }
13003                if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) {
13004                        tableName = getResultSetWithId("RESULT_OF_" + tableModel.getAlias());
13005
13006                } else {
13007                        tableName = getResultSetDisplayId("RS");
13008                }
13009                modelManager.DISPLAY_NAME.put(tableModel.getId(), tableName);
13010                return tableName;
13011        }
13012
13013        private String getProcedureName(Procedure procedureModel) {
13014                if (modelManager.DISPLAY_NAME.containsKey(procedureModel.getId())) {
13015                        return modelManager.DISPLAY_NAME.get(procedureModel.getId());
13016                }
13017
13018                String procedureName = procedureModel.getFullName();
13019
13020                modelManager.DISPLAY_NAME.put(procedureModel.getId(), procedureName);
13021                return procedureName;
13022        }
13023
13024        private String getProcessName(Process processModel) {
13025                if (modelManager.DISPLAY_NAME.containsKey(processModel.getId())) {
13026                        return modelManager.DISPLAY_NAME.get(processModel.getId());
13027                } else {
13028                        if (processModel.getCustomType() != null) {
13029                                String name = processModel.getCustomType();
13030                                modelManager.DISPLAY_NAME.put(processModel.getId(), name);
13031                                return name;
13032                        }
13033                        String name = processModel.getType();
13034                        String procedureName = getProcedureParentName(processModel.getGspObject());
13035                        if (procedureName != null) {
13036                                name = getResultSetDisplayId(procedureName + " " + name);
13037                        } else {
13038                                name = getResultSetDisplayId("Query " + name);
13039                        }
13040                        modelManager.DISPLAY_NAME.put(processModel.getId(), name);
13041                        return name;
13042                }
13043        }
13044
13045        private String getDisplayIdByType(String type) {
13046                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13047                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
13048                        return type + "-" + (option.getStartId() + 1);
13049                } else {
13050                        long id = modelManager.DISPLAY_ID.get(type);
13051                        modelManager.DISPLAY_ID.put(type, id + 1);
13052                        return type + "-" + (id + 1);
13053                }
13054        }
13055        
13056        private String getDisplayIdByTypeFromZero(String type) {
13057                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13058                        modelManager.DISPLAY_ID.put(type, option.getStartId());
13059                        if(option.getStartId() == 0) {
13060                                return type;
13061                        }
13062                        return type + "-" + (option.getStartId() + 1);
13063                } else {
13064                        long id = modelManager.DISPLAY_ID.get(type);
13065                        modelManager.DISPLAY_ID.put(type, id + 1);
13066                        return type + "-" + (id + 1);
13067                }
13068        }
13069
13070        private String getConstantName(Table tableModel) {
13071                if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) {
13072                        return modelManager.DISPLAY_NAME.get(tableModel.getId());
13073                } else {
13074                        String name = getDisplayIdByType("SQL_CONSTANTS");
13075                        modelManager.DISPLAY_NAME.put(tableModel.getId(), name);
13076                        return name;
13077                }
13078        }
13079        
13080        private String getTempTableName(TTable table) {
13081                if (modelManager.DISPLAY_NAME.containsKey((long)System.identityHashCode(table))) {
13082                        return modelManager.DISPLAY_NAME.get((long)System.identityHashCode(table));
13083                } else {
13084                        String name = getDisplayIdByTypeFromZero(table.getName());
13085                        modelManager.DISPLAY_NAME.put((long)System.identityHashCode(table), name);
13086                        return name;
13087                }
13088        }
13089
13090        private String getResultSetName(ResultSet resultSetModel) {
13091
13092                if (modelManager.DISPLAY_NAME.containsKey(resultSetModel.getId())) {
13093                        return modelManager.DISPLAY_NAME.get(resultSetModel.getId());
13094                }
13095                
13096                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) {
13097                        String name = getResultSetDisplayId("ARRAY");
13098                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13099                        if(option.containsResultSetType(ResultSetType.array)) {
13100                                resultSetModel.setTarget(true);
13101                        }
13102                        return name;
13103                }
13104                
13105                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) {
13106                        String name = getResultSetDisplayId("STRUCT");
13107                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13108                        if(option.containsResultSetType(ResultSetType.struct)) {
13109                                resultSetModel.setTarget(true);
13110                        }
13111                        return name;
13112                }
13113
13114                if (resultSetModel instanceof QueryTable) {
13115                        QueryTable table = (QueryTable) resultSetModel;
13116                        if (table.getAlias() != null && table.getAlias().trim().length() > 0) {
13117                                String name = getResultSetWithId("RESULT_OF_" + table.getAlias().trim());
13118                                if (table.getTableObject().getCTE() != null) {
13119                                        name = getResultSetWithId("RESULT_OF_" + table.getTableObject().getCTE().getTableName().toString()
13120                                                        + "_" + table.getAlias().trim());
13121                                }
13122                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13123                                if(option.containsResultSetType(ResultSetType.result_of)) {
13124                                        resultSetModel.setTarget(true);
13125                                }
13126                                return name;
13127                        } else if (table.getTableObject().getCTE() != null) {
13128                                String name = getResultSetWithId("CTE-" + table.getTableObject().getCTE().getTableName().toString());
13129                                modelManager.DISPLAY_NAME.put(table.getId(), name);
13130                                if(option.containsResultSetType(ResultSetType.cte)) {
13131                                        resultSetModel.setTarget(true);
13132                                }
13133                                return name;
13134                        }
13135                }
13136
13137                if (resultSetModel instanceof SelectResultSet) {
13138                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) {
13139                                String name = getResultSetDisplayId("INSERT-SELECT");
13140                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13141                                if(option.containsResultSetType(ResultSetType.insert_select)) {
13142                                        resultSetModel.setTarget(true);
13143                                }
13144                                return name;
13145                        }
13146
13147                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) {
13148                                String name = getResultSetDisplayId("UPDATE-SELECT");
13149                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13150                                if(option.containsResultSetType(ResultSetType.update_select)) {
13151                                        resultSetModel.setTarget(true);
13152                                }
13153                                return name;
13154                        }
13155                }
13156
13157                if (resultSetModel instanceof SelectSetResultSet) {
13158                        ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType();
13159                        String name = getResultSetDisplayId("RESULT_OF_" + type.name().toUpperCase());
13160                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13161                        if(option.containsResultSetType(ResultSetType.result_of)) {
13162                                resultSetModel.setTarget(true);
13163                        }
13164                        return name;
13165                }
13166
13167                if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) {
13168                        String name = getResultSetDisplayId("MERGE-UPDATE");
13169                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13170                        if(option.containsResultSetType(ResultSetType.merge_update)) {
13171                                resultSetModel.setTarget(true);
13172                        }
13173                        return name;
13174                }
13175
13176                if (resultSetModel.getGspObject() instanceof TOutputClause) {
13177                        String name = getResultSetDisplayId("OUTPUT");
13178                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13179                        if(option.containsResultSetType(ResultSetType.output)) {
13180                                resultSetModel.setTarget(true);
13181                        }
13182                        return name;
13183                }
13184
13185                if (resultSetModel.getGspObject() instanceof TMergeInsertClause) {
13186                        String name = getResultSetDisplayId("MERGE-INSERT");
13187                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13188                        if(option.containsResultSetType(ResultSetType.merge_insert)) {
13189                                resultSetModel.setTarget(true);
13190                        }
13191                        return name;
13192                }
13193
13194                if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) {
13195                        String name = getResultSetDisplayId("UPDATE-SET");
13196                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13197                        if(option.containsResultSetType(ResultSetType.update_set)) {
13198                                resultSetModel.setTarget(true);
13199                        }
13200                        return name;
13201                }
13202
13203                if (resultSetModel.getGspObject() instanceof TCaseExpression) {
13204                        String name = ((Function) resultSetModel).getFunctionName();
13205                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13206                        if (option.containsResultSetType(ResultSetType.case_when) || option.containsResultSetType(ResultSetType.function)) {
13207                                resultSetModel.setTarget(true);
13208                        }
13209                        return name;
13210                }
13211                
13212                if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) {
13213                        String name = ((Function) resultSetModel).getFunctionName();
13214                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13215                        if(option.containsResultSetType(ResultSetType.function)) {
13216                                resultSetModel.setTarget(true);
13217                        }
13218                        return name;
13219                }
13220
13221                if (resultSetModel instanceof PivotedTable) {
13222                        String name = getResultSetDisplayId("PIVOT-TABLE");
13223                        if (((PivotedTable) resultSetModel).isUnpivoted()) {
13224                                name = getResultSetDisplayId("UNPIVOT-TABLE");
13225                                if(option.containsResultSetType(ResultSetType.unpivot_table)) {
13226                                        resultSetModel.setTarget(true);
13227                                }
13228                        }
13229                        else {
13230                                if(option.containsResultSetType(ResultSetType.pivot_table)) {
13231                                        resultSetModel.setTarget(true);
13232                                }
13233                        }
13234                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13235                        return name;
13236                }
13237
13238                if (resultSetModel instanceof Alias) {
13239                        String name = getResultSetDisplayId("ALIAS");
13240                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13241                        if(option.containsResultSetType(ResultSetType.alias)) {
13242                                resultSetModel.setTarget(true);
13243                        }
13244                        return name;
13245                }
13246
13247                String name = getResultSetDisplayId("RS");
13248                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13249                if(option.containsResultSetType(ResultSetType.select_list)) {
13250                        resultSetModel.setTarget(true);
13251                }
13252                return name;
13253        }
13254
13255        private String getResultSetWithId(String type) {
13256                type = DlineageUtil.getIdentifierNormalTableName(type);
13257                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13258                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
13259                        return type + "-" + (option.getStartId() + 1);
13260                } else {
13261                        long id = modelManager.DISPLAY_ID.get(type);
13262                        modelManager.DISPLAY_ID.put(type, id + 1);
13263                        return type + "-" + (id + 1);
13264                }
13265        }
13266
13267        private String getResultSetDisplayId(String type) {
13268                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13269                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
13270                        return type + "-" + (option.getStartId() + 1);
13271                } else {
13272                        long id = modelManager.DISPLAY_ID.get(type);
13273                        modelManager.DISPLAY_ID.put(type, id + 1);
13274                        return type + "-" + (id + 1);
13275                }
13276        }
13277
13278        private void appendViews(dataflow dataflow) {
13279                List<TCustomSqlStatement> views = modelManager.getViews();
13280                for (int i = 0; i < views.size(); i++) {
13281                        Table viewModel = (Table) modelManager.getViewModel(views.get(i));
13282                        if (!tableIds.contains(viewModel.getId())) {
13283                                appendViewModel(dataflow, viewModel);
13284                                tableIds.add(viewModel.getId());
13285                        }
13286                }
13287
13288                List<TTable> tables = modelManager.getBaseTables();
13289                for (int i = 0; i < tables.size(); i++) {
13290                        Object model = modelManager.getModel(tables.get(i));
13291                        if (model instanceof Table) {
13292                                Table tableModel = (Table) model;
13293                                if (tableModel.isView()) {
13294                                        if (!tableIds.contains(tableModel.getId())) {
13295                                                appendViewModel(dataflow, tableModel);
13296                                                tableIds.add(tableModel.getId());
13297                                        }
13298                                }
13299                        }
13300                }
13301
13302                List<Table> tableNames = modelManager.getTablesByName();
13303                for (int i = 0; i < tableNames.size(); i++) {
13304                        Table tableModel = tableNames.get(i);
13305                        if (tableModel.isView()) {
13306                                if (!tableIds.contains(tableModel.getId())) {
13307                                        appendViewModel(dataflow, tableModel);
13308                                        tableIds.add(tableModel.getId());
13309                                }
13310                        }
13311                }
13312        }
13313
13314        private void appendViewModel(dataflow dataflow, Table viewModel) {
13315                table viewElement = new table();
13316                viewElement.setId(String.valueOf(viewModel.getId()));
13317                if (!SQLUtil.isEmpty(viewModel.getDatabase())) {
13318                        viewElement.setDatabase(viewModel.getDatabase());
13319                }
13320                if (!SQLUtil.isEmpty(viewModel.getSchema())) {
13321                        viewElement.setSchema(viewModel.getSchema());
13322                }
13323                viewElement.setServer(viewModel.getServer());
13324                viewElement.setName(viewModel.getName());
13325                viewElement.setType("view");
13326                viewElement.setStarStmt(viewModel.getStarStmt());
13327
13328                if(viewModel.isFromDDL()){
13329                        viewElement.setFromDDL(String.valueOf(viewModel.isFromDDL()));
13330                }
13331
13332                if (viewModel.getStartPosition() != null && viewModel.getEndPosition() != null) {
13333                        viewElement.setCoordinate(convertCoordinate(viewModel.getStartPosition()) + ","
13334                                        + convertCoordinate(viewModel.getEndPosition()));
13335                }
13336                if (viewModel.getProcesses() != null) {
13337                        List<String> processIds = new ArrayList<String>();
13338                        for (Process process : viewModel.getProcesses()) {
13339                                processIds.add(String.valueOf(process.getId()));
13340                        }
13341                        viewElement.setProcessIds(processIds);
13342                }
13343                dataflow.getViews().add(viewElement);
13344
13345                List<TableColumn> columns = viewModel.getColumns();
13346
13347                if (containStarColumn(columns)) {
13348                        for (TableColumn column : columns) {
13349                                if (column.getName().endsWith("*")) {
13350                                        for (TableColumn starElement : columns) {
13351                                                if (starElement == column) {
13352                                                        continue;
13353                                                }
13354                                                TObjectName columnObject = starElement.getColumnObject();
13355                                                column.bindStarLinkColumn(columnObject);
13356                                        }
13357                                        if (viewModel.isCreateTable()) {
13358                                                column.setShowStar(false);
13359                                        }
13360                                }
13361                        }
13362                }
13363
13364                for (int j = 0; j < columns.size(); j++) {
13365                        TableColumn columnModel = (TableColumn) columns.get(j);
13366                        if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn()) {
13367                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
13368                                for (int k = 0; k < starLinkColumnList.size(); k++) {
13369                                        column columnElement = new column();
13370                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
13371                                        String columnName = starLinkColumnList.get(k);
13372                                        if (containStarColumn(columns, columnName)) {
13373                                                continue;
13374                                        }
13375                                        columnElement.setName(columnName);
13376                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13377                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13378                                                                + convertCoordinate(columnModel.getEndPosition()));
13379                                        }
13380                                        viewElement.getColumns().add(columnElement);
13381                                }
13382
13383                                if (columnModel.isShowStar()) {
13384                                        column columnElement = new column();
13385                                        columnElement.setId(String.valueOf(columnModel.getId()));
13386                                        columnElement.setName(columnModel.getName());
13387                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13388                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13389                                                                + convertCoordinate(columnModel.getEndPosition()));
13390                                        }
13391                                        viewElement.getColumns().add(columnElement);
13392                                }
13393
13394                        } else {
13395                                column columnElement = new column();
13396                                columnElement.setId(String.valueOf(columnModel.getId()));
13397                                columnElement.setName(columnModel.getName());
13398                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13399                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13400                                                        + convertCoordinate(columnModel.getEndPosition()));
13401                                }
13402                                if(columnModel.isPseduo()) {
13403                                        columnElement.setSource("system");
13404                                }
13405                                viewElement.getColumns().add(columnElement);
13406                        }
13407                }
13408
13409                TableRelationRows relationRows = viewModel.getRelationRows();
13410                if (relationRows.hasRelation()) {
13411                        column relationRowsElement = new column();
13412                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13413                        relationRowsElement.setName(relationRows.getName());
13414                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13415                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13416                                                + convertCoordinate(relationRows.getEndPosition()));
13417                        }
13418                        relationRowsElement.setSource("system");
13419                        viewElement.getColumns().add(relationRowsElement);
13420                }
13421        }
13422
13423        private void appendStreamModel(dataflow dataflow, Table streamModel) {
13424                table streamElement = new table();
13425                streamElement.setId(String.valueOf(streamModel.getId()));
13426                if (!SQLUtil.isEmpty(streamModel.getDatabase())) {
13427                        streamElement.setDatabase(streamModel.getDatabase());
13428                }
13429                if (!SQLUtil.isEmpty(streamModel.getSchema())) {
13430                        streamElement.setSchema(streamModel.getSchema());
13431                }
13432                streamElement.setServer(streamModel.getServer());
13433                streamElement.setName(streamModel.getName());
13434                streamElement.setType("stream");
13435                if (streamModel.getFileType() != null) {
13436                        streamElement.setFileType(SQLUtil.trimColumnStringQuote(streamModel.getFileType()));
13437                }
13438
13439                if (streamModel.getStartPosition() != null && streamModel.getEndPosition() != null) {
13440                        streamElement.setCoordinate(convertCoordinate(streamModel.getStartPosition()) + ","
13441                                        + convertCoordinate(streamModel.getEndPosition()));
13442                }
13443
13444                if (streamModel.getProcesses() != null) {
13445                        List<String> processIds = new ArrayList<String>();
13446                        for (Process process : streamModel.getProcesses()) {
13447                                processIds.add(String.valueOf(process.getId()));
13448                        }
13449                        streamElement.setProcessIds(processIds);
13450                }
13451                dataflow.getStreams().add(streamElement);
13452
13453                List<TableColumn> columns = streamModel.getColumns();
13454
13455                for (int j = 0; j < columns.size(); j++) {
13456                        TableColumn columnModel = (TableColumn) columns.get(j);
13457                        column columnElement = new column();
13458                        columnElement.setId(String.valueOf(columnModel.getId()));
13459                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13460                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13461                                        + convertCoordinate(columnModel.getEndPosition()));
13462                        streamElement.getColumns().add(columnElement);
13463                }
13464
13465                TableRelationRows relationRows = streamModel.getRelationRows();
13466                if (relationRows.hasRelation()) {
13467                        column relationRowsElement = new column();
13468                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13469                        relationRowsElement.setName(relationRows.getName());
13470                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13471                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13472                                                + convertCoordinate(relationRows.getEndPosition()));
13473                        }
13474                        relationRowsElement.setSource("system");
13475                        streamElement.getColumns().add(relationRowsElement);
13476                }
13477        }
13478
13479        private void appendStageModel(dataflow dataflow, Table stageModel) {
13480                table stageElement = new table();
13481                stageElement.setId(String.valueOf(stageModel.getId()));
13482                if (!SQLUtil.isEmpty(stageModel.getDatabase())) {
13483                        stageElement.setDatabase(stageModel.getDatabase());
13484                }
13485                if (!SQLUtil.isEmpty(stageModel.getSchema())) {
13486                        stageElement.setSchema(stageModel.getSchema());
13487                }
13488                stageElement.setServer(stageModel.getServer());
13489                stageElement.setName(stageModel.getName());
13490                stageElement.setType("stage");
13491                stageElement.setLocation(stageModel.getLocation());
13492                if (stageModel.getFileType() != null) {
13493                        stageElement.setFileType(SQLUtil.trimColumnStringQuote(stageModel.getFileType()));
13494                }
13495
13496                if (stageModel.getStartPosition() != null && stageModel.getEndPosition() != null) {
13497                        stageElement.setCoordinate(convertCoordinate(stageModel.getStartPosition()) + ","
13498                                        + convertCoordinate(stageModel.getEndPosition()));
13499                }
13500
13501                if (stageModel.getProcesses() != null) {
13502                        List<String> processIds = new ArrayList<String>();
13503                        for (Process process : stageModel.getProcesses()) {
13504                                processIds.add(String.valueOf(process.getId()));
13505                        }
13506                        stageElement.setProcessIds(processIds);
13507                }
13508                dataflow.getStages().add(stageElement);
13509
13510                List<TableColumn> columns = stageModel.getColumns();
13511
13512                for (int j = 0; j < columns.size(); j++) {
13513                        TableColumn columnModel = (TableColumn) columns.get(j);
13514                        column columnElement = new column();
13515                        columnElement.setId(String.valueOf(columnModel.getId()));
13516                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13517                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13518                                        + convertCoordinate(columnModel.getEndPosition()));
13519                        stageElement.getColumns().add(columnElement);
13520                }
13521
13522                TableRelationRows relationRows = stageModel.getRelationRows();
13523                if (relationRows.hasRelation()) {
13524                        column relationRowsElement = new column();
13525                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13526                        relationRowsElement.setName(relationRows.getName());
13527                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13528                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13529                                                + convertCoordinate(relationRows.getEndPosition()));
13530                        }
13531                        relationRowsElement.setSource("system");
13532                        stageElement.getColumns().add(relationRowsElement);
13533                }
13534        }
13535
13536        private void appendSequenceModel(dataflow dataflow, Table sequenceModel) {
13537                table sequenceElement = new table();
13538                sequenceElement.setId(String.valueOf(sequenceModel.getId()));
13539                if (!SQLUtil.isEmpty(sequenceModel.getDatabase())) {
13540                        sequenceElement.setDatabase(sequenceModel.getDatabase());
13541                }
13542                if (!SQLUtil.isEmpty(sequenceModel.getSchema())) {
13543                        sequenceElement.setSchema(sequenceModel.getSchema());
13544                }
13545                sequenceElement.setServer(sequenceModel.getServer());
13546                sequenceElement.setName(sequenceModel.getName());
13547                sequenceElement.setType("sequence");
13548                sequenceElement.setLocation(sequenceModel.getLocation());
13549                if (sequenceModel.getFileType() != null) {
13550                        sequenceElement.setFileType(SQLUtil.trimColumnStringQuote(sequenceModel.getFileType()));
13551                }
13552
13553                if (sequenceModel.getStartPosition() != null && sequenceModel.getEndPosition() != null) {
13554                        sequenceElement.setCoordinate(convertCoordinate(sequenceModel.getStartPosition()) + ","
13555                                        + convertCoordinate(sequenceModel.getEndPosition()));
13556                }
13557
13558                if (sequenceModel.getProcesses() != null) {
13559                        List<String> processIds = new ArrayList<String>();
13560                        for (Process process : sequenceModel.getProcesses()) {
13561                                processIds.add(String.valueOf(process.getId()));
13562                        }
13563                        sequenceElement.setProcessIds(processIds);
13564                }
13565                dataflow.getSequences().add(sequenceElement);
13566
13567                List<TableColumn> columns = sequenceModel.getColumns();
13568
13569                for (int j = 0; j < columns.size(); j++) {
13570                        TableColumn columnModel = (TableColumn) columns.get(j);
13571                        column columnElement = new column();
13572                        columnElement.setId(String.valueOf(columnModel.getId()));
13573                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13574                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13575                                        + convertCoordinate(columnModel.getEndPosition()));
13576                        sequenceElement.getColumns().add(columnElement);
13577                }
13578
13579                TableRelationRows relationRows = sequenceModel.getRelationRows();
13580                if (relationRows.hasRelation()) {
13581                        column relationRowsElement = new column();
13582                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13583                        relationRowsElement.setName(relationRows.getName());
13584                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13585                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13586                                                + convertCoordinate(relationRows.getEndPosition()));
13587                        }
13588                        relationRowsElement.setSource("system");
13589                        sequenceElement.getColumns().add(relationRowsElement);
13590                }
13591        }
13592
13593        private void appendDataSourceModel(dataflow dataflow, Table datasourceModel) {
13594                table datasourceElement = new table();
13595                datasourceElement.setId(String.valueOf(datasourceModel.getId()));
13596                if (!SQLUtil.isEmpty(datasourceModel.getDatabase())) {
13597                        datasourceElement.setDatabase(datasourceModel.getDatabase());
13598                }
13599                if (!SQLUtil.isEmpty(datasourceModel.getSchema())) {
13600                        datasourceElement.setSchema(datasourceModel.getSchema());
13601                }
13602                datasourceElement.setServer(datasourceModel.getServer());
13603                datasourceElement.setName(datasourceModel.getName());
13604                datasourceElement.setType("datasource");
13605                datasourceElement.setLocation(datasourceModel.getLocation());
13606                if (datasourceModel.getFileType() != null) {
13607                        datasourceElement.setFileType(SQLUtil.trimColumnStringQuote(datasourceModel.getFileType()));
13608                }
13609
13610                if (datasourceModel.getStartPosition() != null && datasourceModel.getEndPosition() != null) {
13611                        datasourceElement.setCoordinate(convertCoordinate(datasourceModel.getStartPosition()) + ","
13612                                        + convertCoordinate(datasourceModel.getEndPosition()));
13613                }
13614
13615                if (datasourceModel.getProcesses() != null) {
13616                        List<String> processIds = new ArrayList<String>();
13617                        for (Process process : datasourceModel.getProcesses()) {
13618                                processIds.add(String.valueOf(process.getId()));
13619                        }
13620                        datasourceElement.setProcessIds(processIds);
13621                }
13622                dataflow.getDatasources().add(datasourceElement);
13623
13624                List<TableColumn> columns = datasourceModel.getColumns();
13625
13626                for (int j = 0; j < columns.size(); j++) {
13627                        TableColumn columnModel = (TableColumn) columns.get(j);
13628                        column columnElement = new column();
13629                        columnElement.setId(String.valueOf(columnModel.getId()));
13630                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13631                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13632                                        + convertCoordinate(columnModel.getEndPosition()));
13633                        datasourceElement.getColumns().add(columnElement);
13634                }
13635
13636                TableRelationRows relationRows = datasourceModel.getRelationRows();
13637                if (relationRows.hasRelation()) {
13638                        column relationRowsElement = new column();
13639                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13640                        relationRowsElement.setName(relationRows.getName());
13641                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13642                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13643                                                + convertCoordinate(relationRows.getEndPosition()));
13644                        }
13645                        relationRowsElement.setSource("system");
13646                        datasourceElement.getColumns().add(relationRowsElement);
13647                }
13648        }
13649
13650        private void appendDatabaseModel(dataflow dataflow, Table databaseModel) {
13651                table databaseElement = new table();
13652                databaseElement.setId(String.valueOf(databaseModel.getId()));
13653                if (!SQLUtil.isEmpty(databaseModel.getDatabase())) {
13654                        databaseElement.setDatabase(databaseModel.getDatabase());
13655                }
13656                if (!SQLUtil.isEmpty(databaseModel.getSchema())) {
13657                        databaseElement.setSchema(databaseModel.getSchema());
13658                }
13659                databaseElement.setServer(databaseModel.getServer());
13660                databaseElement.setName(databaseModel.getName());
13661                databaseElement.setType("database");
13662                if (databaseModel.getFileType() != null) {
13663                        databaseElement.setFileType(SQLUtil.trimColumnStringQuote(databaseModel.getFileType()));
13664                }
13665
13666                if (databaseModel.getStartPosition() != null && databaseModel.getEndPosition() != null) {
13667                        databaseElement.setCoordinate(convertCoordinate(databaseModel.getStartPosition()) + ","
13668                                        + convertCoordinate(databaseModel.getEndPosition()));
13669                }
13670
13671                if (databaseModel.getProcesses() != null) {
13672                        List<String> processIds = new ArrayList<String>();
13673                        for (Process process : databaseModel.getProcesses()) {
13674                                processIds.add(String.valueOf(process.getId()));
13675                        }
13676                        databaseElement.setProcessIds(processIds);
13677                }
13678                dataflow.getDatabases().add(databaseElement);
13679
13680                List<TableColumn> columns = databaseModel.getColumns();
13681
13682                for (int j = 0; j < columns.size(); j++) {
13683                        TableColumn columnModel = (TableColumn) columns.get(j);
13684                        column columnElement = new column();
13685                        columnElement.setId(String.valueOf(columnModel.getId()));
13686                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13687                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13688                                        + convertCoordinate(columnModel.getEndPosition()));
13689                        databaseElement.getColumns().add(columnElement);
13690                }
13691
13692                TableRelationRows relationRows = databaseModel.getRelationRows();
13693                if (relationRows.hasRelation()) {
13694                        column relationRowsElement = new column();
13695                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13696                        relationRowsElement.setName(relationRows.getName());
13697                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13698                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13699                                                + convertCoordinate(relationRows.getEndPosition()));
13700                        }
13701                        relationRowsElement.setSource("system");
13702                        databaseElement.getColumns().add(relationRowsElement);
13703                }
13704        }
13705
13706        private void appendSchemaModel(dataflow dataflow, Table schemaModel) {
13707                table schemaElement = new table();
13708                schemaElement.setId(String.valueOf(schemaModel.getId()));
13709                if (!SQLUtil.isEmpty(schemaModel.getDatabase())) {
13710                        schemaElement.setDatabase(schemaModel.getDatabase());
13711                }
13712                if (!SQLUtil.isEmpty(schemaModel.getSchema())) {
13713                        schemaElement.setSchema(schemaModel.getSchema());
13714                }
13715                schemaElement.setServer(schemaModel.getServer());
13716                schemaElement.setName(schemaModel.getName());
13717                schemaElement.setType("schema");
13718                if (schemaModel.getFileType() != null) {
13719                        schemaElement.setFileType(SQLUtil.trimColumnStringQuote(schemaModel.getFileType()));
13720                }
13721
13722                if (schemaModel.getStartPosition() != null && schemaModel.getEndPosition() != null) {
13723                        schemaElement.setCoordinate(convertCoordinate(schemaModel.getStartPosition()) + ","
13724                                        + convertCoordinate(schemaModel.getEndPosition()));
13725                }
13726
13727                if (schemaModel.getProcesses() != null) {
13728                        List<String> processIds = new ArrayList<String>();
13729                        for (Process process : schemaModel.getProcesses()) {
13730                                processIds.add(String.valueOf(process.getId()));
13731                        }
13732                        schemaElement.setProcessIds(processIds);
13733                }
13734                dataflow.getSchemas().add(schemaElement);
13735
13736                List<TableColumn> columns = schemaModel.getColumns();
13737
13738                for (int j = 0; j < columns.size(); j++) {
13739                        TableColumn columnModel = (TableColumn) columns.get(j);
13740                        column columnElement = new column();
13741                        columnElement.setId(String.valueOf(columnModel.getId()));
13742                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13743                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13744                                        + convertCoordinate(columnModel.getEndPosition()));
13745                        schemaElement.getColumns().add(columnElement);
13746                }
13747
13748                TableRelationRows relationRows = schemaModel.getRelationRows();
13749                if (relationRows.hasRelation()) {
13750                        column relationRowsElement = new column();
13751                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13752                        relationRowsElement.setName(relationRows.getName());
13753                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13754                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13755                                                + convertCoordinate(relationRows.getEndPosition()));
13756                        }
13757                        relationRowsElement.setSource("system");
13758                        schemaElement.getColumns().add(relationRowsElement);
13759                }
13760        }
13761
13762        private void appendPathModel(dataflow dataflow, Table pathModel) {
13763                table pathElement = new table();
13764                pathElement.setId(String.valueOf(pathModel.getId()));
13765                if (!SQLUtil.isEmpty(pathModel.getDatabase())) {
13766                        pathElement.setDatabase(pathModel.getDatabase());
13767                }
13768                if (!SQLUtil.isEmpty(pathModel.getSchema())) {
13769                        pathElement.setSchema(pathModel.getSchema());
13770                }
13771                pathElement.setServer(pathModel.getServer());
13772                pathElement.setName(pathModel.getName());
13773                pathElement.setType("path");
13774                if (pathModel.getFileFormat() != null) {
13775                        pathElement.setFileFormat(SQLUtil.trimColumnStringQuote(pathModel.getFileFormat()));
13776                }
13777
13778                if (pathModel.getStartPosition() != null && pathModel.getEndPosition() != null) {
13779                        pathElement.setCoordinate(convertCoordinate(pathModel.getStartPosition()) + ","
13780                                        + convertCoordinate(pathModel.getEndPosition()));
13781                }
13782
13783                if (pathModel.getProcesses() != null) {
13784                        List<String> processIds = new ArrayList<String>();
13785                        for (Process process : pathModel.getProcesses()) {
13786                                processIds.add(String.valueOf(process.getId()));
13787                        }
13788                        pathElement.setProcessIds(processIds);
13789                }
13790
13791                pathElement.setUri(pathModel.getName());
13792
13793                dataflow.getPaths().add(pathElement);
13794
13795                List<TableColumn> columns = pathModel.getColumns();
13796
13797                for (int j = 0; j < columns.size(); j++) {
13798                        TableColumn columnModel = (TableColumn) columns.get(j);
13799                        column columnElement = new column();
13800                        columnElement.setId(String.valueOf(columnModel.getId()));
13801                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13802                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13803                                        + convertCoordinate(columnModel.getEndPosition()));
13804                        pathElement.getColumns().add(columnElement);
13805                }
13806
13807                TableRelationRows relationRows = pathModel.getRelationRows();
13808                if (relationRows.hasRelation()) {
13809                        column relationRowsElement = new column();
13810                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13811                        relationRowsElement.setName(relationRows.getName());
13812                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13813                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13814                                                + convertCoordinate(relationRows.getEndPosition()));
13815                        }
13816                        relationRowsElement.setSource("system");
13817                        pathElement.getColumns().add(relationRowsElement);
13818                }
13819        }
13820
13821        private void appendVariableModel(dataflow dataflow, Table variableModel) {
13822                table variableElement = new table();
13823                variableElement.setId(String.valueOf(variableModel.getId()));
13824                if (!SQLUtil.isEmpty(variableModel.getDatabase())) {
13825                        variableElement.setDatabase(variableModel.getDatabase());
13826                }
13827                if (!SQLUtil.isEmpty(variableModel.getSchema())) {
13828                        variableElement.setSchema(variableModel.getSchema());
13829                }
13830                variableElement.setServer(variableModel.getServer());
13831                variableElement.setName(variableModel.getName());
13832                variableElement.setType("variable");
13833                variableElement.setParent(variableModel.getParent());
13834                if (variableModel.getSubType() != null) {
13835                        variableElement.setSubType(variableModel.getSubType().name());
13836                }
13837
13838                if (variableModel.getStartPosition() != null && variableModel.getEndPosition() != null) {
13839                        variableElement.setCoordinate(convertCoordinate(variableModel.getStartPosition()) + ","
13840                                        + convertCoordinate(variableModel.getEndPosition()));
13841                }
13842                dataflow.getVariables().add(variableElement);
13843
13844                List<TableColumn> columns = variableModel.getColumns();
13845
13846                if (containStarColumn(columns)) {
13847                        for (TableColumn column : columns) {
13848                                if (column.getName().endsWith("*")) {
13849                                        for (TableColumn starElement : columns) {
13850                                                if (starElement == column) {
13851                                                        continue;
13852                                                }
13853                                                TObjectName columnObject = starElement.getColumnObject();
13854                                                column.bindStarLinkColumn(columnObject);
13855                                        }
13856//                                      column.setShowStar(false);
13857                                }
13858                        }
13859                }
13860
13861                for (int j = 0; j < columns.size(); j++) {
13862                        TableColumn columnModel = columns.get(j);
13863                        if (columnModel.hasStarLinkColumn()) {
13864                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
13865                                for (int k = 0; k < starLinkColumnList.size(); k++) {
13866                                        column columnElement = new column();
13867                                        columnElement.setId(columnModel.getId() + "_" + k);
13868                                        String columnName = starLinkColumnList.get(k);
13869                                        if (containStarColumn(columns, columnName)) {
13870                                                continue;
13871                                        }
13872                                        columnElement.setName(columnName);
13873                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13874                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13875                                                                + convertCoordinate(columnModel.getEndPosition()));
13876                                        }
13877                                        variableElement.getColumns().add(columnElement);
13878                                }
13879
13880                                if (columnModel.isShowStar()) {
13881                                        column columnElement = new column();
13882                                        columnElement.setId(String.valueOf(columnModel.getId()));
13883                                        columnElement.setName(columnModel.getName());
13884                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13885                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13886                                                                + convertCoordinate(columnModel.getEndPosition()));
13887                                        }
13888                                        variableElement.getColumns().add(columnElement);
13889                                }
13890
13891                        } else {
13892                                column columnElement = new column();
13893                                columnElement.setId(String.valueOf(columnModel.getId()));
13894                                columnElement.setName(columnModel.getName());
13895                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13896                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13897                                                        + convertCoordinate(columnModel.getEndPosition()));
13898                                }
13899                                variableElement.getColumns().add(columnElement);
13900                        }
13901                }
13902
13903                TableRelationRows relationRows = variableModel.getRelationRows();
13904                if (relationRows.hasRelation()) {
13905                        column relationRowsElement = new column();
13906                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13907                        relationRowsElement.setName(relationRows.getName());
13908                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13909                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13910                                                + convertCoordinate(relationRows.getEndPosition()));
13911                        }
13912                        relationRowsElement.setSource("system");
13913                        variableElement.getColumns().add(relationRowsElement);
13914                }
13915        }
13916
13917        private void appendCursorModel(dataflow dataflow, Table cursorModel) {
13918                table cursorElement = new table();
13919                cursorElement.setId(String.valueOf(cursorModel.getId()));
13920                if (!SQLUtil.isEmpty(cursorModel.getDatabase())) {
13921                        cursorElement.setDatabase(cursorModel.getDatabase());
13922                }
13923                if (!SQLUtil.isEmpty(cursorModel.getSchema())) {
13924                        cursorElement.setSchema(cursorModel.getSchema());
13925                }
13926                cursorElement.setServer(cursorModel.getServer());
13927                cursorElement.setName(cursorModel.getName());
13928                cursorElement.setType("variable");
13929                if (cursorElement.getSubType() != null) {
13930                        cursorElement.setSubType(cursorModel.getSubType().name());
13931                }
13932
13933                if (cursorModel.getStartPosition() != null && cursorModel.getEndPosition() != null) {
13934                        cursorElement.setCoordinate(convertCoordinate(cursorModel.getStartPosition()) + ","
13935                                        + convertCoordinate(cursorModel.getEndPosition()));
13936                }
13937                dataflow.getVariables().add(cursorElement);
13938
13939                List<TableColumn> columns = cursorModel.getColumns();
13940
13941                if (containStarColumn(columns)) {
13942                        for (TableColumn column : columns) {
13943                                if (column.getName().endsWith("*")) {
13944                                        for (TableColumn starElement : columns) {
13945                                                if (starElement == column) {
13946                                                        continue;
13947                                                }
13948                                                TObjectName columnObject = starElement.getColumnObject();
13949                                                column.bindStarLinkColumn(columnObject);
13950                                        }
13951                                        column.setShowStar(false);
13952                                }
13953                        }
13954                }
13955
13956                for (int j = 0; j < columns.size(); j++) {
13957                        TableColumn columnModel = (TableColumn) columns.get(j);
13958                        if (columnModel.hasStarLinkColumn()) {
13959                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
13960                                for (int k = 0; k < starLinkColumnList.size(); k++) {
13961                                        column columnElement = new column();
13962                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
13963                                        String columnName = starLinkColumnList.get(k);
13964                                        if (containStarColumn(columns, columnName)) {
13965                                                continue;
13966                                        }
13967                                        columnElement.setName(columnName);
13968                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13969                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13970                                                                + convertCoordinate(columnModel.getEndPosition()));
13971                                        }
13972                                        cursorElement.getColumns().add(columnElement);
13973                                }
13974
13975                                if (columnModel.isShowStar()) {
13976                                        column columnElement = new column();
13977                                        columnElement.setId(String.valueOf(columnModel.getId()));
13978                                        columnElement.setName(columnModel.getName());
13979                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13980                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13981                                                                + convertCoordinate(columnModel.getEndPosition()));
13982                                        }
13983                                        cursorElement.getColumns().add(columnElement);
13984                                }
13985
13986                        } else {
13987                                column columnElement = new column();
13988                                columnElement.setId(String.valueOf(columnModel.getId()));
13989                                columnElement.setName(columnModel.getName());
13990                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13991                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13992                                                        + convertCoordinate(columnModel.getEndPosition()));
13993                                }
13994                                cursorElement.getColumns().add(columnElement);
13995                        }
13996                }
13997
13998                TableRelationRows relationRows = cursorModel.getRelationRows();
13999                if (relationRows.hasRelation()) {
14000                        column relationRowsElement = new column();
14001                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
14002                        relationRowsElement.setName(relationRows.getName());
14003                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
14004                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
14005                                                + convertCoordinate(relationRows.getEndPosition()));
14006                        }
14007                        relationRowsElement.setSource("system");
14008                        cursorElement.getColumns().add(relationRowsElement);
14009                }
14010        }
14011
14012        private void appendErrors(dataflow dataflow) {
14013                List<ErrorInfo> errorInfos = this.getErrorMessages();
14014                if (metadataErrors != null) {
14015                        for (int i = 0; i < metadataErrors.size(); i++) {
14016                                errorInfos.add(i, metadataErrors.get(i));
14017                        }
14018                }
14019
14020                for (int i = 0; i < errorInfos.size(); ++i) {
14021                        ErrorInfo errorInfo = errorInfos.get(i);
14022                        error error = new error();
14023                        if (!SQLUtil.isEmpty(errorInfo.getErrorMessage())) {
14024                                error.setErrorMessage(errorInfo.getErrorMessage());
14025                        }
14026                        if (!SQLUtil.isEmpty(errorInfo.getErrorType())) {
14027                                error.setErrorType(errorInfo.getErrorType());
14028                        }
14029                        if (errorInfo.getStartPosition() != null && errorInfo.getEndPosition() != null) {
14030                                error.setCoordinate(convertCoordinate(errorInfo.getStartPosition()) + ","
14031                                                + convertCoordinate(errorInfo.getEndPosition()));
14032                        }
14033                        if (!SQLUtil.isEmpty(errorInfo.getFileName())) {
14034                                error.setFile(errorInfo.getFileName());
14035                        }
14036                        if (errorInfo.getOriginStartPosition() != null && errorInfo.getOriginEndPosition() != null) {
14037                                error.setOriginCoordinate(errorInfo.getOriginStartPosition() + "," + errorInfo.getOriginEndPosition());
14038                        }
14039                        dataflow.getErrors().add(error);
14040                }
14041        }
14042
14043        private void appendOraclePackages(dataflow dataflow) {
14044                List<OraclePackage> packages = this.modelManager.getOraclePackageModels();
14045
14046                for (int i = 0; i < packages.size(); ++i) {
14047                        OraclePackage model = packages.get(i);
14048                        oraclePackage oraclePackage = new oraclePackage();
14049                        oraclePackage.setId(String.valueOf(model.getId()));
14050                        if (!SQLUtil.isEmpty(model.getDatabase())) {
14051                                oraclePackage.setDatabase(model.getDatabase());
14052                        }
14053                        if (!SQLUtil.isEmpty(model.getSchema())) {
14054                                oraclePackage.setSchema(model.getSchema());
14055                        }
14056                        oraclePackage.setServer(model.getServer());
14057                        oraclePackage.setName(model.getName());
14058                        if (model.getType() != null) {
14059                                oraclePackage.setType(model.getType().name().replace("sst", ""));
14060                        }
14061                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
14062                                oraclePackage.setCoordinate(
14063                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
14064                        }
14065
14066                        dataflow.getPackages().add(oraclePackage);
14067
14068                        List<Argument> arguments = model.getArguments();
14069
14070                        for (int j = 0; j < arguments.size(); ++j) {
14071                                Argument argumentModel = (Argument) arguments.get(j);
14072                                argument argumentElement = new argument();
14073                                argumentElement.setId(String.valueOf(argumentModel.getId()));
14074                                argumentElement.setName(argumentModel.getName());
14075                                if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
14076                                        argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
14077                                                        + convertCoordinate(argumentModel.getEndPosition()));
14078                                }
14079
14080                                argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
14081                                argumentElement.setInout(argumentModel.getMode().name());
14082                                oraclePackage.getArguments().add(argumentElement);
14083                        }
14084
14085                        for (int j = 0; j < model.getProcedures().size(); j++) {
14086                                Procedure procedureModel = model.getProcedures().get(j);
14087                                procedure procedure = new procedure();
14088                                procedure.setId(String.valueOf(procedureModel.getId()));
14089                                if (!SQLUtil.isEmpty(procedureModel.getDatabase())) {
14090                                        procedure.setDatabase(procedureModel.getDatabase());
14091                                }
14092                                if (!SQLUtil.isEmpty(procedureModel.getSchema())) {
14093                                        procedure.setSchema(procedureModel.getSchema());
14094                                }
14095                                procedure.setServer(procedureModel.getServer());
14096                                procedure.setName(procedureModel.getName());
14097                                if (procedureModel.getType() != null) {
14098                                        procedure.setType(procedureModel.getType().name().replace("sst", ""));
14099                                }
14100                                if (procedureModel.getStartPosition() != null && procedureModel.getEndPosition() != null) {
14101                                        procedure.setCoordinate(convertCoordinate(procedureModel.getStartPosition()) + ","
14102                                                        + convertCoordinate(procedureModel.getEndPosition()));
14103                                }
14104
14105                                oraclePackage.getProcedures().add(procedure);
14106
14107                                List<Argument> procedureArguments = procedureModel.getArguments();
14108
14109                                for (int k = 0; k < procedureArguments.size(); ++k) {
14110                                        Argument argumentModel = (Argument) procedureArguments.get(k);
14111                                        argument argumentElement = new argument();
14112                                        argumentElement.setId(String.valueOf(argumentModel.getId()));
14113                                        argumentElement.setName(argumentModel.getName());
14114                                        if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
14115                                                argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
14116                                                                + convertCoordinate(argumentModel.getEndPosition()));
14117                                        }
14118
14119                                        argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
14120                                        argumentElement.setInout(argumentModel.getMode().name());
14121                                        procedure.getArguments().add(argumentElement);
14122                                }
14123                        }
14124                }
14125        }
14126
14127        private void appendProcedures(dataflow dataflow) {
14128                List<Procedure> procedures = this.modelManager.getProcedureModels();
14129
14130                for (int i = 0; i < procedures.size(); ++i) {
14131                        Procedure model = procedures.get(i);
14132                        if (model.getParentPackage() != null) {
14133                                continue;
14134                        }
14135                        procedure procedure = new procedure();
14136                        procedure.setId(String.valueOf(model.getId()));
14137                        if (!SQLUtil.isEmpty(model.getDatabase())) {
14138                                procedure.setDatabase(model.getDatabase());
14139                        }
14140                        if (!SQLUtil.isEmpty(model.getSchema())) {
14141                                procedure.setSchema(model.getSchema());
14142                        }
14143                        procedure.setServer(model.getServer());
14144                        procedure.setName(model.getName());
14145                        if (model.getType() != null) {
14146                                procedure.setType(model.getType().name().replace("sst", ""));
14147                        }
14148                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
14149                                procedure.setCoordinate(
14150                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
14151                        }
14152
14153                        dataflow.getProcedures().add(procedure);
14154
14155                        List<Argument> arguments = model.getArguments();
14156
14157                        for (int j = 0; j < arguments.size(); ++j) {
14158                                Argument argumentModel = (Argument) arguments.get(j);
14159                                argument argumentElement = new argument();
14160                                argumentElement.setId(String.valueOf(argumentModel.getId()));
14161                                argumentElement.setName(argumentModel.getName());
14162                                if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
14163                                        argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
14164                                                        + convertCoordinate(argumentModel.getEndPosition()));
14165                                }
14166
14167                                argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
14168                                argumentElement.setInout(argumentModel.getMode().name());
14169                                procedure.getArguments().add(argumentElement);
14170                        }
14171                }
14172        }
14173
14174        private void appendProcesses(dataflow dataflow) {
14175                List<Process> processes = this.modelManager.getProcessModels();
14176
14177                for (int i = 0; i < processes.size(); ++i) {
14178                        Process model = processes.get(i);
14179                        process process = new process();
14180                        process.setId(String.valueOf(model.getId()));
14181                        if (!SQLUtil.isEmpty(model.getDatabase())) {
14182                                process.setDatabase(model.getDatabase());
14183                        }
14184                        if (!SQLUtil.isEmpty(model.getSchema())) {
14185                                process.setSchema(model.getSchema());
14186                        }
14187                        process.setServer(model.getServer());
14188                        process.setName(getProcessName(model));
14189                        if (!SQLUtil.isEmpty(model.getProcedureName())) {
14190                                process.setProcedureName(model.getProcedureName());
14191                        }
14192                        if (model.getProcedureId() != null) {
14193                                process.setProcedureId(String.valueOf(model.getProcedureId()));
14194                        }
14195                        if (!SQLUtil.isEmpty(model.getQueryHashId())) {
14196                                process.setQueryHashId(model.getQueryHashId());
14197                        }
14198                        if (model.getGspObject() != null) {
14199                                process.setType(model.getGspObject().sqlstatementtype.name());
14200                        }
14201                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
14202                                process.setCoordinate(
14203                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
14204                        }
14205                        if (model.getTransforms() != null && !model.getTransforms().isEmpty()) {
14206                                for (Transform transformItem : model.getTransforms()) {
14207                                        process.addTransform(transformItem);
14208                                }
14209                        }
14210                        dataflow.getProcesses().add(process);
14211                }
14212        }
14213
14214        private void appendTables(dataflow dataflow) {
14215                List<TTable> tables = modelManager.getBaseTables();
14216                Map<String, table> tableMap = new HashMap<String, table>();
14217                Set<Long> tableModelIds = new HashSet<Long>();
14218                for (int i = 0; i < tables.size(); i++) {
14219                        Object model = modelManager.getModel(tables.get(i));
14220                        if (model instanceof Table) {
14221                                Table tableModel = (Table) model;
14222                                if(tableModelIds.contains(tableModel.getId())) {
14223                                        continue;
14224                                }
14225                                else {
14226                                        tableModelIds.add(tableModel.getId());
14227                                }
14228                                if (tableModel.isView()) {
14229                                        continue;
14230                                }
14231                                if (tableModel.isStage()) {
14232                                        appendStageModel(dataflow, tableModel);
14233                                        continue;
14234                                }
14235                                if (tableModel.isSequence()) {
14236                                        appendSequenceModel(dataflow, tableModel);
14237                                        continue;
14238                                }
14239                                if (tableModel.isDataSource()) {
14240                                        appendDataSourceModel(dataflow, tableModel);
14241                                        continue;
14242                                }
14243                                if (tableModel.isDatabase()) {
14244                                        appendDatabaseModel(dataflow, tableModel);
14245                                        continue;
14246                                }
14247                                if (tableModel.isSchema()) {
14248                                        appendSchemaModel(dataflow, tableModel);
14249                                        continue;
14250                                }
14251                                if (tableModel.isStream()) {
14252                                        appendStreamModel(dataflow, tableModel);
14253                                        continue;
14254                                }
14255                                if (tableModel.isPath()) {
14256                                        appendPathModel(dataflow, tableModel);
14257                                        continue;
14258                                }
14259                                if (tableModel.isVariable() && !tableModel.isCursor()) {
14260                                        appendVariableModel(dataflow, tableModel);
14261                                        continue;
14262                                }
14263                                if (tableModel.isCursor()) {
14264                                        appendCursorModel(dataflow, tableModel);
14265                                        continue;
14266                                }
14267                                if (tableModel.isConstant()) {
14268                                        appendConstantModel(dataflow, tableModel);
14269                                        continue;
14270                                }
14271                                if (!tableIds.contains(tableModel.getId())) {
14272                                        appendTableModel(dataflow, tableModel, tableMap);
14273                                        tableIds.add(tableModel.getId());
14274                                }
14275                        } else if (model instanceof QueryTable) {
14276                                QueryTable queryTable = (QueryTable) model;
14277                                if (!tableIds.contains(queryTable.getId())) {
14278                                        appendResultSet(dataflow, queryTable);
14279                                        tableIds.add(queryTable.getId());
14280                                }
14281                        }
14282                }
14283
14284                List<Table> tableNames = modelManager.getTablesByName();
14285                tableNames.addAll(modelManager.getDropTables());
14286                
14287                for (int i = 0; i < tableNames.size(); i++) {
14288                        Table tableModel = tableNames.get(i);
14289                        if(tableModelIds.contains(tableModel.getId())) {
14290                                continue;
14291                        }
14292                        else {
14293                                tableModelIds.add(tableModel.getId());
14294                        }
14295                        if (tableModel.isView()) {
14296                                continue;
14297                        }
14298                        if (tableModel.isDatabase()) {
14299                                appendDatabaseModel(dataflow, tableModel);
14300                                continue;
14301                        }
14302                        if (tableModel.isSchema()) {
14303                                appendSchemaModel(dataflow, tableModel);
14304                                continue;
14305                        }
14306                        if (tableModel.isStage()) {
14307                                appendStageModel(dataflow, tableModel);
14308                                continue;
14309                        }
14310                        if (tableModel.isSequence()) {
14311                                appendSequenceModel(dataflow, tableModel);
14312                                continue;
14313                        }
14314                        if (tableModel.isDataSource()) {
14315                                appendDataSourceModel(dataflow, tableModel);
14316                                continue;
14317                        }
14318                        if (tableModel.isStream()) {
14319                                appendStreamModel(dataflow, tableModel);
14320                                continue;
14321                        }
14322                        if (tableModel.isPath()) {
14323                                appendPathModel(dataflow, tableModel);
14324                                continue;
14325                        }
14326                        if (tableModel.isVariable()) {
14327                                appendVariableModel(dataflow, tableModel);
14328                                continue;
14329                        }
14330                        if (tableModel.isCursor()) {
14331                                appendCursorModel(dataflow, tableModel);
14332                                continue;
14333                        }
14334                        if (tableModel.isConstant()) {
14335                                appendConstantModel(dataflow, tableModel);
14336                                continue;
14337                        }
14338                        if (!tableIds.contains(tableModel.getId())) {
14339                                appendTableModel(dataflow, tableModel, tableMap);
14340                                tableIds.add(tableModel.getId());
14341                        }
14342                }
14343        }
14344
14345        private void appendConstantModel(dataflow dataflow, Table tableModel) {
14346                table constantElement = new table();
14347                constantElement.setId(String.valueOf(tableModel.getId()));
14348                if (!SQLUtil.isEmpty(tableModel.getDatabase())) {
14349                        constantElement.setDatabase(tableModel.getDatabase());
14350                }
14351                if (!SQLUtil.isEmpty(tableModel.getSchema())) {
14352                        constantElement.setSchema(tableModel.getSchema());
14353                }
14354                constantElement.setServer(tableModel.getServer());
14355                constantElement.setName(getConstantName(tableModel));
14356                constantElement.setType("constantTable");
14357
14358                if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) {
14359                        constantElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + ","
14360                                        + convertCoordinate(tableModel.getEndPosition()));
14361                }
14362                dataflow.getTables().add(constantElement);
14363
14364                List<TableColumn> columns = tableModel.getColumns();
14365                for (int j = 0; j < columns.size(); j++) {
14366                        TableColumn columnModel = (TableColumn) columns.get(j);
14367                        column columnElement = new column();
14368                        columnElement.setId(String.valueOf(columnModel.getId()));
14369                        columnElement.setName(columnModel.getName());
14370                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14371                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14372                                                + convertCoordinate(columnModel.getEndPosition()));
14373                        }
14374                        constantElement.getColumns().add(columnElement);
14375                }
14376        }
14377
14378        private void appendTableModel(dataflow dataflow, Table tableModel, Map<String, table> tableMap) {
14379                if(tableModel.getSubType() == SubType.unnest) {}
14380                table tableElement = new table();
14381                tableElement.setId(String.valueOf(tableModel.getId()));
14382                if (!SQLUtil.isEmpty(tableModel.getDatabase())) {
14383                        tableElement.setDatabase(tableModel.getDatabase());
14384                }
14385                if (!SQLUtil.isEmpty(tableModel.getSchema())) {
14386                        tableElement.setSchema(tableModel.getSchema());
14387                }
14388                tableElement.setServer(tableModel.getServer());
14389                tableElement.setName(tableModel.getName());
14390                tableElement.setDisplayName(tableModel.getDisplayName());
14391                tableElement.setStarStmt(tableModel.getStarStmt());
14392                if(tableModel.isFromDDL()) {
14393                        tableElement.setFromDDL(String.valueOf(tableModel.isFromDDL()));
14394                }
14395
14396                if (tableModel.isPseudo()) {
14397                        tableElement.setType("pseudoTable");
14398                } else {
14399                        tableElement.setType("table");
14400                }
14401
14402                if (tableModel.getSubType() != null) {
14403                        if (tableModel.getSubType() == SubType.unnest) {
14404                                tableElement.setType(SubType.unnest.name());
14405                        }
14406                        else {
14407                                tableElement.setSubType(tableModel.getSubType().name());
14408                        }
14409                }
14410                if (tableModel.getParent() != null) {
14411                        tableElement.setParent(tableModel.getParent());
14412                }
14413                if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) {
14414                        tableElement.setAlias(tableModel.getAlias());
14415                }
14416                if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) {
14417                        tableElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + ","
14418                                        + convertCoordinate(tableModel.getEndPosition()));
14419                }
14420                if (tableModel.getProcesses() != null) {
14421                        List<String> processIds = new ArrayList<String>();
14422                        for (Process process : tableModel.getProcesses()) {
14423                                processIds.add(String.valueOf(process.getId()));
14424                        }
14425                        tableElement.setProcessIds(processIds);
14426                }
14427
14428                table oldTableElement = null;
14429                String tableFullName = DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getQualifiedTableName(tableElement));
14430                
14431                if(tableMap.containsKey(tableFullName)) {
14432                        oldTableElement = tableMap.get(tableFullName);
14433                }
14434                else {
14435                        tableMap.put(tableFullName, tableElement);
14436                }
14437                
14438                if (tableModel.getSubType() == SubType.unnest) {
14439                        dataflow.getResultsets().add(tableElement);
14440                } else {
14441                        dataflow.getTables().add(tableElement);
14442                }
14443
14444                List<TableColumn> columns = tableModel.getColumns();
14445
14446                if (containStarColumn(columns)) {
14447                        for (TableColumn column : columns) {
14448                                if (column.getName().endsWith("*")) {
14449                                        for (TableColumn starElement : columns) {
14450                                                if (starElement == column) {
14451                                                        continue;
14452                                                }
14453                                                if (starElement.isNotBindStarLinkColumn()) {
14454                                                        continue;
14455                                                }
14456                                                TObjectName columnObject = starElement.getColumnObject();
14457                                                column.bindStarLinkColumn(columnObject);
14458                                        }
14459                                        if (tableModel.isCreateTable() && column.isExpandStar()) {
14460                                                column.setShowStar(false);
14461                                        }
14462                                }
14463                        }
14464                }
14465
14466                for (int j = 0; j < columns.size(); j++) {
14467                        TableColumn columnModel = columns.get(j);
14468
14469                        if(oldTableElement != null){
14470                                if(!CollectionUtil.isEmpty(oldTableElement.getColumns())){
14471                                        for(column oldColumnElement: oldTableElement.getColumns()){
14472                                                if(oldColumnElement.getName().equalsIgnoreCase(columnModel.getName())){
14473                                                        if(columnModel.getDataType() == null && oldColumnElement.getDataType() != null){
14474                                                                columnModel.setDataType(oldColumnElement.getDataType());
14475                                                        }
14476                                                        if(columnModel.getPrimaryKey() == null && oldColumnElement.isPrimaryKey() != null){
14477                                                                columnModel.setPrimaryKey(oldColumnElement.isPrimaryKey());
14478                                                        }
14479                                                        if(columnModel.getIndexKey() == null && oldColumnElement.isIndexKey() != null){
14480                                                                columnModel.setIndexKey(oldColumnElement.isIndexKey());
14481                                                        }
14482                                                        if(columnModel.getUnqiueKey() == null && oldColumnElement.isUnqiueKey() != null){
14483                                                                columnModel.setUnqiueKey(oldColumnElement.isUnqiueKey());
14484                                                        }
14485                                                        if(columnModel.getForeignKey() == null && oldColumnElement.isForeignKey() != null){
14486                                                                columnModel.setForeignKey(oldColumnElement.isForeignKey());
14487                                                        }
14488
14489                                                        if(oldColumnElement.getDataType() == null && columnModel.getDataType() != null){
14490                                                                oldColumnElement.setDataType(columnModel.getDataType());
14491                                                        }
14492                                                        if(oldColumnElement.isPrimaryKey() == null && columnModel.getPrimaryKey() != null){
14493                                                                oldColumnElement.setPrimaryKey(columnModel.getPrimaryKey());
14494                                                        }
14495                                                        if(oldColumnElement.isIndexKey() == null && columnModel.getIndexKey() != null){
14496                                                                oldColumnElement.setIndexKey(columnModel.getIndexKey());
14497                                                        }
14498                                                        if(oldColumnElement.isUnqiueKey() == null && columnModel.getUnqiueKey() != null){
14499                                                                oldColumnElement.setUnqiueKey(columnModel.getUnqiueKey());
14500                                                        }
14501                                                        if(oldColumnElement.isForeignKey() == null && columnModel.getForeignKey() != null){
14502                                                                oldColumnElement.setForeignKey(columnModel.getForeignKey());
14503                                                        }
14504                                                        break;
14505                                                }
14506                                        }
14507                                }
14508
14509                        }
14510
14511                        if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn() && !columnModel.isVariant()) {
14512                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
14513                                for (int k = 0; k < starLinkColumnList.size(); k++) {
14514                                        column columnElement = new column();
14515                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
14516                                        String columnName = starLinkColumnList.get(k);
14517                                        if (containStarColumn(columns, columnName)) {
14518                                                continue;
14519                                        }
14520                                        columnElement.setName(columnName);
14521                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14522                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14523                                                                + convertCoordinate(columnModel.getEndPosition()));
14524                                        }
14525                                        if (columnModel.getForeignKey()) {
14526                                                columnElement.setForeignKey(columnModel.getForeignKey());
14527                                        }
14528                                        if (columnModel.getIndexKey()) {
14529                                                columnElement.setIndexKey(columnModel.getIndexKey());
14530                                        }
14531                                        if (columnModel.getPrimaryKey()) {
14532                                                columnElement.setPrimaryKey(columnModel.getPrimaryKey());
14533                                        }
14534                                        if (columnModel.getUnqiueKey()) {
14535                                                columnElement.setUnqiueKey(columnModel.getUnqiueKey());
14536                                        }
14537                                        if (columnModel.getDataType() != null) {
14538                                                columnElement.setDataType(columnModel.getDataType());
14539                                        }
14540                                        tableElement.getColumns().add(columnElement);
14541                                }
14542                                if (columnModel.isShowStar()) {
14543                                        column columnElement = new column();
14544                                        columnElement.setId(String.valueOf(columnModel.getId()));
14545                                        columnElement.setName(columnModel.getName());
14546                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14547                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14548                                                                + convertCoordinate(columnModel.getEndPosition()));
14549                                        }
14550                                        if (columnModel.getForeignKey()) {
14551                                                columnElement.setForeignKey(columnModel.getForeignKey());
14552                                        }
14553                                        if (columnModel.getIndexKey()) {
14554                                                columnElement.setIndexKey(columnModel.getIndexKey());
14555                                        }
14556                                        if (columnModel.getPrimaryKey()) {
14557                                                columnElement.setPrimaryKey(columnModel.getPrimaryKey());
14558                                        }
14559                                        if (columnModel.getUnqiueKey()) {
14560                                                columnElement.setUnqiueKey(columnModel.getUnqiueKey());
14561                                        }
14562                                        if (columnModel.getDataType() != null) {
14563                                                columnElement.setDataType(columnModel.getDataType());
14564                                        }
14565                                        tableElement.getColumns().add(columnElement);
14566                                }
14567                        } else {
14568                                column columnElement = new column();
14569                                columnElement.setId(String.valueOf(columnModel.getId()));
14570                                columnElement.setName(columnModel.getName());
14571                                columnElement.setDisplayName(columnModel.getDisplayName());
14572                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14573                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14574                                                        + convertCoordinate(columnModel.getEndPosition()));
14575                                }
14576                                if (columnModel.isPseduo()) {
14577                                        columnElement.setSource("system");
14578                                }
14579                                if (columnModel.getForeignKey()) {
14580                                        columnElement.setForeignKey(columnModel.getForeignKey());
14581                                }
14582                                if (columnModel.getIndexKey()) {
14583                                        columnElement.setIndexKey(columnModel.getIndexKey());
14584                                }
14585                                if (columnModel.getPrimaryKey()) {
14586                                        columnElement.setPrimaryKey(columnModel.getPrimaryKey());
14587                                }
14588                                if (columnModel.getUnqiueKey()) {
14589                                        columnElement.setUnqiueKey(columnModel.getUnqiueKey());
14590                                }
14591                                if (columnModel.getDataType() != null) {
14592                                        columnElement.setDataType(columnModel.getDataType());
14593                                }
14594                                tableElement.getColumns().add(columnElement);
14595                        }
14596                }
14597
14598                TableRelationRows relationRows = tableModel.getRelationRows();
14599                if (relationRows.hasRelation()) {
14600                        column relationRowsElement = new column();
14601                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
14602                        relationRowsElement.setName(relationRows.getName());
14603                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
14604                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
14605                                                + convertCoordinate(relationRows.getEndPosition()));
14606                        }
14607                        relationRowsElement.setSource("system");
14608                        tableElement.getColumns().add(relationRowsElement);
14609                }
14610        }
14611
14612        private boolean containStarColumn(List<TableColumn> columns, String qualifiedColumnName) {
14613                for (TableColumn tableColumn : columns) {
14614                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) {
14615                                return true;
14616                        }
14617                }
14618                return false;
14619        }
14620
14621        private TableColumn searchTableColumn(List<TableColumn> columns, String qualifiedColumnName) {
14622                for (TableColumn tableColumn : columns) {
14623                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) {
14624                                return tableColumn;
14625                        }
14626                }
14627                return null;
14628        }
14629
14630        private boolean containStarColumn(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) {
14631                for (RelationshipElement element : elements) {
14632                        if (element.getElement() instanceof TableColumn) {
14633                                if (DlineageUtil.getIdentifierNormalColumnName(((TableColumn) element.getElement()).getName())
14634                                                .equals(qualifiedColumnName)) {
14635                                        return true;
14636                                }
14637                        } else if (element.getElement() instanceof ResultColumn) {
14638                                if (DlineageUtil.getIdentifierNormalColumnName(((ResultColumn) element.getElement()).getName())
14639                                                .equals(qualifiedColumnName)) {
14640                                        return true;
14641                                }
14642                        }
14643                }
14644                return false;
14645        }
14646
14647        private void analyzeSelectStmt(TSelectSqlStatement stmt) {
14648                if (!accessedSubqueries.contains(stmt)) {
14649                        accessedSubqueries.add(stmt);
14650                } else {
14651                        if (modelManager.getModel(stmt) != null) {
14652                                return;
14653                        }
14654                }
14655
14656                if (stmt.getParentStmt() == null && stmt.getIntoClause() == null && stmt.getIntoTableClause() == null) {
14657                        if(option.isIgnoreTopSelect() && (option.isIgnoreRecordSet() || option.isSimpleOutput())){
14658                                if(option.getAnalyzeMode() == null || option.getAnalyzeMode() == AnalyzeMode.dataflow){
14659                                        return;
14660                                }
14661                        }
14662                }
14663
14664                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
14665
14666                        if (!accessedStatements.contains(stmt.getLeftStmt())) {
14667                                accessedStatements.add(stmt.getLeftStmt());
14668                                analyzeSelectStmt(stmt.getLeftStmt());
14669                        }
14670
14671                        if (!accessedStatements.contains(stmt.getRightStmt())) {
14672                                accessedStatements.add(stmt.getRightStmt());
14673                                analyzeSelectStmt(stmt.getRightStmt());
14674                        }
14675
14676                        stmtStack.push(stmt);
14677                        SelectSetResultSet resultSet = modelFactory.createSelectSetResultSet(stmt);
14678
14679                        ResultSet leftResultSetModel = (ResultSet) modelManager.getModel(stmt.getLeftStmt());
14680                        if (leftResultSetModel != null && leftResultSetModel != resultSet
14681                                        && !leftResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
14682                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14683                                impactRelation.setEffectType(EffectType.select);
14684                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14685                                                leftResultSetModel.getRelationRows()));
14686                                impactRelation.setTarget(
14687                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
14688                        }
14689                        
14690                        ResultSet rightResultSetModel = (ResultSet) modelManager.getModel(stmt.getRightStmt());
14691                        if (rightResultSetModel != null && rightResultSetModel != resultSet
14692                                        && !rightResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
14693                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14694                                impactRelation.setEffectType(EffectType.select);
14695                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14696                                                rightResultSetModel.getRelationRows()));
14697                                impactRelation.setTarget(
14698                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
14699                        }
14700                        
14701                        if ((leftResultSetModel != null && leftResultSetModel.isDetermined())
14702                                        || (rightResultSetModel != null && rightResultSetModel.isDetermined())) {
14703                                resultSet.setDetermined(true);
14704                        }
14705                        
14706                        if (resultSet.getColumns() == null || resultSet.getColumns().isEmpty()) {
14707                                if (getResultColumnList(stmt.getLeftStmt()) != null) {
14708                                        createSelectSetResultColumns(resultSet, stmt.getLeftStmt());
14709                                } else if (getResultColumnList(stmt.getRightStmt()) != null) {
14710                                        createSelectSetResultColumns(resultSet, stmt.getRightStmt());
14711                                }
14712                        }
14713
14714                        List<ResultColumn> columns = resultSet.getColumns();
14715                        for (int i = 0; i < columns.size(); i++) {
14716                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14717                                relation.setEffectType(EffectType.select);
14718                                relation.setTarget(new ResultColumnRelationshipElement(columns.get(i)));
14719
14720                                if (!stmt.getLeftStmt().isCombinedQuery()) {
14721                                        ResultSet sourceResultSet = (ResultSet) modelManager
14722                                                        .getModel(stmt.getLeftStmt().getResultColumnList());
14723                                        if (sourceResultSet!=null && sourceResultSet.getColumns().size() > i) {
14724                                                if (columns.get(i).getName().endsWith("*")) {
14725                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
14726                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14727                                                        }
14728                                                } else {
14729                                                        relation.addSource(
14730                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
14731                                                }
14732                                        }
14733                                } else {
14734                                        ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getLeftStmt());
14735                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
14736                                                if (columns.get(i).getName().endsWith("*")) {
14737                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
14738                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14739                                                        }
14740                                                } else {
14741                                                        relation.addSource(
14742                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
14743                                                }
14744                                        }
14745                                }
14746
14747                                if (!stmt.getRightStmt().isCombinedQuery()) {
14748                                        ResultSet sourceResultSet = (ResultSet) modelManager
14749                                                        .getModel(stmt.getRightStmt().getResultColumnList());
14750                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
14751                                                if (columns.get(i).getName().endsWith("*")) {
14752                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
14753                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14754                                                        }
14755                                                } else {
14756                                                        relation.addSource(
14757                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
14758                                                }
14759                                        } else if (sourceResultSet != null) {
14760                                                for (ResultColumn column : sourceResultSet.getColumns()) {
14761                                                        if (column.hasStarLinkColumn()) {
14762                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14763                                                        }
14764                                                }
14765                                        }
14766                                } else {
14767                                        ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getRightStmt());
14768                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
14769                                                relation.addSource(new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
14770                                        } else if (sourceResultSet != null) {
14771                                                for (ResultColumn column : sourceResultSet.getColumns()) {
14772                                                        if (column.hasStarLinkColumn()) {
14773                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14774                                                        }
14775                                                }
14776                                        }
14777                                }
14778                        }
14779                        
14780                        analyzeSelectIntoClause(stmt);
14781                        
14782                        stmtStack.pop();
14783                } else {
14784
14785                        // handle hive stmt, issue_id I3SGZB
14786                        if (stmt.getHiveBodyList() != null && stmt.getHiveBodyList().size() > 0) {
14787                                stmtStack.push(stmt);
14788                                hiveFromTables = stmt.tables;
14789                                if (hiveFromTables != null) {
14790                                        for (int i = 0; i < hiveFromTables.size(); i++) {
14791                                                modelFactory.createTable(hiveFromTables.getTable(i));
14792                                        }
14793                                }
14794                                for (int i = 0; i < stmt.getHiveBodyList().size(); i++) {
14795                                        analyzeCustomSqlStmt(stmt.getHiveBodyList().get(i));
14796                                }
14797                                stmtStack.pop();
14798                                return;
14799                        }
14800                        
14801                        if (stmt.getTransformClause() != null) {
14802                                analyzeHiveTransformClause(stmt, stmt.getTransformClause());
14803                                return;
14804                        }
14805
14806                        if (stmt.getResultColumnList() == null) {
14807                                return;
14808                        }
14809
14810                        stmtStack.push(stmt);
14811
14812                        TTableList fromTables = stmt.tables;
14813                        if ((fromTables == null || fromTables.size() == 0)
14814                                        && (hiveFromTables != null && hiveFromTables.size() > 0)) {
14815                                fromTables = hiveFromTables;
14816                        }
14817
14818                        for (int i = 0; i < fromTables.size(); i++) {
14819                                TTable table = fromTables.getTable(i);
14820                                if (table.getLateralViewList() != null && !table.getLateralViewList().isEmpty()) {
14821                                        analyzeTableSubquery(table);
14822                                        analyzeLateralView(stmt, table, table.getLateralViewList());
14823                                        stmtStack.pop();
14824                                        return;
14825                                }
14826                                if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvpresto) {
14827                                        analyzeTableSubquery(table);
14828                                        analyzePrestoUnnest(stmt, table);
14829                                        stmtStack.pop();
14830                                        return;
14831                                }
14832                                if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvbigquery) {
14833                                        analyzeBigQueryUnnest(stmt, table);
14834                                }
14835                        }
14836                        
14837                        //用来获取 pivotedTable 对应的columns
14838                        TPivotedTable pivotedTable = null; 
14839                        if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
14840                                for (TJoin join : stmt.getJoins()) {
14841                                        if (join.getTable() != null && join.getTable().getPivotedTable() != null) {
14842                                                if (isUnPivotedTable(join.getTable().getPivotedTable())) {
14843                                                        analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable());
14844                                                        pivotedTable = join.getTable().getPivotedTable();
14845                                                } else {
14846                                                        analyzePivotedTable(stmt, join.getTable().getPivotedTable());
14847                                                        pivotedTable = join.getTable().getPivotedTable();
14848                                                }
14849                                        }
14850                                }
14851                        }
14852
14853                        for (int i = 0; i < fromTables.size(); i++) {
14854                                TTable table = fromTables.getTable(i);
14855
14856                                if (table.getFuncCall() != null) {
14857                                        TFunctionCall functionCall = table.getFuncCall();
14858                                        Procedure callee = modelManager.getProcedureByName(
14859                                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
14860                                        if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
14861                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
14862                                                callee = modelManager.getProcedureByName(
14863                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
14864                                        }
14865
14866                                        if(callee!=null) {
14867                                                if (callee.getArguments() != null) {
14868                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
14869                                                                Argument argument = callee.getArguments().get(j);
14870                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
14871                                                                if(variable!=null) {
14872                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
14873                                                                                Transform transform = new Transform();
14874                                                                                transform.setType(Transform.FUNCTION);
14875                                                                                transform.setCode(functionCall);
14876                                                                                variable.getColumns().get(0).setTransform(transform);
14877                                                                        }
14878                                                                        Process process = modelFactory.createProcess(functionCall);
14879                                                                        variable.addProcess(process);
14880                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
14881                                                                }
14882                                                        }
14883                                                }
14884                                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
14885                                                                .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
14886                                                if (functionTableModelObjs != null) {
14887                                                        modelManager.bindModel(table, functionTableModelObjs.iterator().next());
14888                                                }
14889                                                continue;
14890                                        } else {
14891                                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
14892                                                                .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
14893                                                if (functionTableModelObjs == null) {
14894//                                                      Procedure procedure = modelManager.getProcedureByName(DlineageUtil
14895//                                                                      .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
14896//                                                      if (procedure != null) {
14897                                                                createFunction(table.getFuncCall());
14898                                                                continue;
14899//                                                      }
14900                                                }
14901                                                if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof Table) {
14902                                                        Table functionTableModel = (Table) functionTableModelObjs.iterator().next();
14903                                                        if (functionTableModel.getColumns() != null) {
14904                                                                Table functionTable = modelFactory.createTableFromCreateDDL(table, true);
14905                                                                if (functionTable == functionTableModel)
14906                                                                        continue;
14907                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
14908                                                                        TableColumn column = modelFactory.createTableColumn(functionTable,
14909                                                                                        functionTableModel.getColumns().get(j).getColumnObject(), true);
14910                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14911                                                                        relation.setEffectType(EffectType.select);
14912                                                                        relation.setTarget(new TableColumnRelationshipElement(column));
14913                                                                        relation.addSource(
14914                                                                                        new TableColumnRelationshipElement(functionTableModel.getColumns().get(j)));
14915                                                                }
14916                                                        }
14917                                                } else if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) {
14918                                                        ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next();
14919                                                        if (functionTableModel.getColumns() != null) {
14920                                                                Table functionTable = modelFactory.createTableFromCreateDDL(table, true);
14921                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
14922                                                                        TParseTreeNode columnObj = functionTableModel.getColumns().get(j).getColumnObject();
14923                                                                        if (columnObj instanceof TObjectName) {
14924                                                                                TableColumn column = modelFactory.createTableColumn(functionTable,
14925                                                                                                (TObjectName) columnObj, true);
14926                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14927                                                                                relation.setEffectType(EffectType.select);
14928                                                                                relation.setTarget(new TableColumnRelationshipElement(column));
14929                                                                                relation.addSource(new ResultColumnRelationshipElement(
14930                                                                                                functionTableModel.getColumns().get(j)));
14931                                                                        } else if (columnObj instanceof TResultColumn) {
14932                                                                                TableColumn column = modelFactory.createTableColumn(functionTable,
14933                                                                                                (TResultColumn) columnObj);
14934                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14935                                                                                relation.setEffectType(EffectType.select);
14936                                                                                relation.setTarget(new TableColumnRelationshipElement(column));
14937                                                                                relation.addSource(new ResultColumnRelationshipElement(
14938                                                                                                functionTableModel.getColumns().get(j)));
14939                                                                        }
14940                                                                }
14941                                                        }
14942                                                }
14943                                        }
14944                                }
14945                                
14946                                if (table.getPartitionExtensionClause() != null
14947                                                && table.getPartitionExtensionClause().getKeyValues() != null) {
14948                                        TExpressionList values = table.getPartitionExtensionClause().getKeyValues();
14949                                        Table tableModel = modelFactory.createTable(table);
14950                                        for (TExpression value : values) {
14951                                                if (value.getExpressionType() == EExpressionType.simple_constant_t) {
14952                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14953                                                        impactRelation.setEffectType(EffectType.select);
14954                                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
14955                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, value.getConstantOperand());
14956                                                        impactRelation.addSource(new TableColumnRelationshipElement(constantColumn));
14957                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
14958                                                                        tableModel.getRelationRows()));
14959                                                }
14960                                        }
14961                                }
14962
14963                                if (table.getSubquery() != null) {
14964                                        QueryTable queryTable = modelFactory.createQueryTable(table);
14965                                        TSelectSqlStatement subquery = table.getSubquery();
14966                                        analyzeSelectStmt(subquery);
14967
14968                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
14969                                        if (resultSetModel != null && resultSetModel.isDetermined()) {
14970                                                queryTable.setDetermined(true);
14971                                        }
14972
14973                                        if (resultSetModel != null && resultSetModel != queryTable
14974                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
14975                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14976                                                impactRelation.setEffectType(EffectType.select);
14977                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14978                                                                resultSetModel.getRelationRows()));
14979                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14980                                                                queryTable.getRelationRows()));
14981                                        }
14982
14983                                        if (resultSetModel != null && resultSetModel != queryTable
14984                                                        && queryTable.getTableObject().getAliasClause() != null
14985                                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
14986                                                for (int j = 0; j < queryTable.getColumns().size()
14987                                                                && j < resultSetModel.getColumns().size(); j++) {
14988                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
14989                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
14990
14991                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
14992                                                        queryRalation.setEffectType(EffectType.select);
14993                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14994                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14995                                                }
14996                                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
14997                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
14998                                                                .getModel(subquery);
14999                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
15000                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
15001                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
15002                                                                        sourceColumn);
15003                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15004                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
15005                                                        }
15006                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15007                                                        selectSetRalation.setEffectType(EffectType.select);
15008                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15009                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15010                                                }
15011                                        }
15012                                } else if (table.getOutputMerge() != null) {
15013                                        QueryTable queryTable = modelFactory.createQueryTable(table);
15014                                        TMergeSqlStatement subquery = table.getOutputMerge();
15015                                        analyzeMergeStmt(subquery);
15016
15017                                        for (TResultColumn column : subquery.getOutputClause().getSelectItemList()) {
15018                                                modelFactory.createResultColumn(queryTable, column);
15019                                                analyzeResultColumn(column, EffectType.select);
15020                                        }
15021
15022                                        ResultSet resultSetModel = (ResultSet) modelManager
15023                                                        .getModel(subquery.getOutputClause().getSelectItemList());
15024
15025                                        if (resultSetModel != null && resultSetModel != queryTable
15026                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15027                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15028                                                impactRelation.setEffectType(EffectType.select);
15029                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15030                                                                resultSetModel.getRelationRows()));
15031                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15032                                                                queryTable.getRelationRows()));
15033                                        }
15034
15035                                        if (resultSetModel != null && resultSetModel != queryTable
15036                                                        && queryTable.getTableObject().getAliasClause() != null
15037                                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
15038                                                for (int j = 0; j < queryTable.getColumns().size()
15039                                                                && j < resultSetModel.getColumns().size(); j++) {
15040                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15041                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
15042
15043                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
15044                                                        queryRalation.setEffectType(EffectType.select);
15045                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15046                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15047                                                }
15048                                        }
15049                                } else if (table.getTableExpr() != null && table.getTableExpr().getSubQuery() != null) {
15050                                        QueryTable queryTable = modelFactory.createQueryTable(table);
15051                                        TSelectSqlStatement subquery = table.getTableExpr().getSubQuery();
15052                                        analyzeSelectStmt(subquery);
15053
15054                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
15055
15056                                        if (resultSetModel != null && resultSetModel != queryTable
15057                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15058                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15059                                                impactRelation.setEffectType(EffectType.select);
15060                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15061                                                                resultSetModel.getRelationRows()));
15062                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15063                                                                queryTable.getRelationRows()));
15064                                        }
15065
15066                                        if (resultSetModel != null && resultSetModel != queryTable
15067                                                        && queryTable.getTableObject().getAliasClause() != null) {
15068                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
15069                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15070                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
15071                                                                        sourceColumn);
15072
15073                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
15074                                                        queryRalation.setEffectType(EffectType.select);
15075                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15076                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15077                                                }
15078                                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
15079                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
15080                                                                .getModel(subquery);
15081                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
15082                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
15083                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
15084                                                                        sourceColumn);
15085                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15086                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
15087                                                        }
15088                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15089                                                        selectSetRalation.setEffectType(EffectType.select);
15090                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15091                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15092                                                }
15093                                        }
15094                                } else if (table.getCTE() != null) {
15095                                        QueryTable queryTable = modelFactory.createQueryTable(table);
15096
15097                                        TObjectNameList cteColumns = table.getCTE().getColumnList();
15098                                        if (cteColumns != null) {
15099                                                for (int j = 0; j < cteColumns.size(); j++) {
15100                                                        modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
15101                                                }
15102                                                queryTable.setDetermined(true);
15103                                        }
15104                                        TSelectSqlStatement subquery = table.getCTE().getSubquery();
15105                                        if (subquery != null && !stmtStack.contains(subquery) && subquery.getResultColumnList() != null) {
15106                                                analyzeSelectStmt(subquery);
15107
15108                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
15109                                                if (resultSetModel != null && resultSetModel != queryTable
15110                                                                && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15111                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15112                                                        impactRelation.setEffectType(EffectType.select);
15113                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15114                                                                        resultSetModel.getRelationRows()));
15115                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15116                                                                        queryTable.getRelationRows()));
15117                                                }
15118
15119                                                if (subquery.getSetOperatorType() != ESetOperatorType.none) {
15120                                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
15121                                                                        .getModel(subquery);
15122                                                        int x = 0;
15123                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
15124                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
15125                                                                ResultColumn targetColumn = null;
15126                                                                if (cteColumns != null) {
15127                                                                        if (queryTable.getColumns().size() <= j) {
15128                                                                                for (int k = 0; k < queryTable.getColumns().size(); k++) {
15129                                                                                        if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName())
15130                                                                                                        || queryTable.getColumns().get(k).getName()
15131                                                                                                                        .equals(sourceColumn.getAlias())) {
15132                                                                                                targetColumn = queryTable.getColumns().get(k);
15133                                                                                        }
15134                                                                                }
15135                                                                        } else {
15136                                                                                if (x < j) {
15137                                                                                        x = j;
15138                                                                                }
15139                                                                                targetColumn = queryTable.getColumns().get(x);
15140                                                                                x++;
15141                                                                                if (resultSetModel.getColumns().get(j).getName().contains("*")
15142                                                                                                && x < cteColumns.size()) {
15143                                                                                        j--;
15144                                                                                }
15145                                                                        }
15146                                                                } else {
15147                                                                        targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
15148                                                                }
15149                                                                for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15150                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
15151                                                                }
15152                                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15153                                                                selectSetRalation.setEffectType(EffectType.select);
15154                                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15155                                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15156                                                        }
15157                                                        if (!queryTable.isDetermined()) {
15158                                                                queryTable.setDetermined(selectSetResultSetModel.isDetermined());
15159                                                        }
15160                                                } else {
15161                                                        int x = 0;
15162                                                        for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
15163                                                                ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15164                                                                ResultColumn targetColumn = null;
15165                                                                if (cteColumns != null) {
15166                                                                        if (queryTable.getColumns().size() <= j) {
15167                                                                                for (int k = 0; k < queryTable.getColumns().size(); k++) {
15168                                                                                        if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName())
15169                                                                                                        || queryTable.getColumns().get(k).getName()
15170                                                                                                                        .equals(sourceColumn.getAlias())) {
15171                                                                                                targetColumn = queryTable.getColumns().get(k);
15172                                                                                        }
15173                                                                                }
15174                                                                        } else {
15175                                                                                if (x < j) {
15176                                                                                        x = j;
15177                                                                                }
15178                                                                                targetColumn = queryTable.getColumns().get(x);
15179                                                                                x++;
15180                                                                                if (resultSetModel.getColumns().get(j).getName().contains("*")
15181                                                                                                && x < cteColumns.size()) {
15182                                                                                        j--;
15183                                                                                }
15184                                                                        }
15185                                                                } else {
15186                                                                        targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
15187                                                                }
15188                                                                for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15189                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
15190                                                                }
15191                                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15192                                                                selectSetRalation.setEffectType(EffectType.select);
15193                                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15194                                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15195                                                        }
15196                                                        if (!queryTable.isDetermined()) {
15197                                                                queryTable.setDetermined(resultSetModel.isDetermined());
15198                                                        }
15199                                                }
15200                                        } else if (table.getCTE().getUpdateStmt() != null) {
15201                                                analyzeCustomSqlStmt(table.getCTE().getUpdateStmt());
15202                                        } else if (table.getCTE().getInsertStmt() != null) {
15203                                                analyzeCustomSqlStmt(table.getCTE().getInsertStmt());
15204                                        } else if (table.getCTE().getDeleteStmt() != null) {
15205                                                analyzeCustomSqlStmt(table.getCTE().getDeleteStmt());
15206                                        }
15207                                } else if (table.getTableType().name().startsWith("open")) {
15208                                        continue;
15209                                } else if (table.getTableType() == ETableSource.jsonTable) {
15210                                        Table functionTable = modelFactory.createJsonTable(table);
15211                                        TJsonTable jsonTable = table.getJsonTable();
15212                                        TColumnDefinitionList definitions = jsonTable.getColumnDefinitions();
15213                                        if (definitions != null) {
15214                                                for (int j = 0; j < definitions.size(); j++) {
15215                                                        TableColumn column = modelFactory.createTableColumn(functionTable,
15216                                                                        definitions.getColumn(j).getColumnName(), true);
15217                                                        if (definitions.getColumn(j).getColumnPath() != null) {
15218                                                                column.setDisplayName(
15219                                                                                column.getName() + ":" + definitions.getColumn(j).getColumnPath());
15220                                                        }
15221                                                }
15222                                        } else {
15223                                                TObjectName keyColumn = new TObjectName();
15224                                                keyColumn.setString("key");
15225                                                modelFactory.createJsonTableColumn(functionTable, keyColumn);
15226                                                TObjectName valueColumn = new TObjectName();
15227                                                valueColumn.setString("value");
15228                                                modelFactory.createJsonTableColumn(functionTable, valueColumn);
15229                                                TObjectName typeColumn = new TObjectName();
15230                                                typeColumn.setString("type");
15231                                                modelFactory.createJsonTableColumn(functionTable, typeColumn);
15232                                        }
15233
15234                                        functionTable.setCreateTable(true);
15235                                        functionTable.setSubType(SubType.function);
15236                                        modelManager.bindCreateModel(table, functionTable);
15237
15238                                        if (jsonTable.getJsonExpression() == null) {
15239                                                ErrorInfo errorInfo = new ErrorInfo();
15240                                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
15241                                                errorInfo.setErrorMessage("Can't handle the json table: " + jsonTable.toString());
15242                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(jsonTable.getStartToken().lineNo,
15243                                                                jsonTable.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
15244                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(jsonTable.getEndToken().lineNo,
15245                                                                jsonTable.getEndToken().columnNo + jsonTable.getEndToken().getAstext().length(),
15246                                                                ModelBindingManager.getGlobalHash()));
15247                                                errorInfo.fillInfo(this);
15248                                                errorInfos.add(errorInfo);
15249                                        } else {
15250                                                String jsonName = jsonTable.getJsonExpression().toString();
15251                                                if (!jsonName.startsWith("@")) {
15252                                                        columnsInExpr visitor = new columnsInExpr();
15253                                                        jsonTable.getJsonExpression().inOrderTraverse(visitor);
15254                                                        List<TObjectName> objectNames = visitor.getObjectNames();
15255                                                        List<TParseTreeNode> functions = visitor.getFunctions();
15256                                                        List<TParseTreeNode> constants = visitor.getConstants();
15257                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15258
15259                                                        for (int j = 0; j < functionTable.getColumns().size(); j++) {
15260                                                                TableColumn tableColumn = functionTable.getColumns().get(j);
15261                                                                if (functions != null && !functions.isEmpty()) {
15262                                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
15263                                                                }
15264                                                                if (subquerys != null && !subquerys.isEmpty()) {
15265                                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
15266                                                                }
15267                                                                if (objectNames != null && !objectNames.isEmpty()) {
15268                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
15269                                                                }
15270                                                                if (constants != null && !constants.isEmpty()) {
15271                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
15272                                                                                        functions);
15273                                                                }
15274                                                        }
15275                                                } else {
15276                                                        TStatementList stmts = stmt.getGsqlparser().getSqlstatements();
15277                                                        for (int j = 0; j < stmts.size(); j++) {
15278                                                                TCustomSqlStatement item = stmts.get(j);
15279                                                                if (item instanceof TMssqlDeclare) {
15280                                                                        if (analyzeMssqlJsonDeclare((TMssqlDeclare) item, jsonName, functionTable)) {
15281                                                                                break;
15282                                                                        }
15283                                                                }
15284                                                        }
15285                                                }
15286                                        }
15287                                } else if (table.getLinkedColumns() != null && table.getLinkedColumns().size() > 0) {
15288                                        if (table.getTableType() == ETableSource.rowList && table.getRowList() != null
15289                                                        && table.getRowList().size() > 0) {
15290                                                Table tableModel = modelFactory.createTable(table);
15291                                                for (int j = 0; j < table.getRowList().size(); j++) {
15292                                                        TMultiTarget rowList = table.getRowList().getMultiTarget(j);
15293                                                        for (int k = 0; k < rowList.getColumnList().size(); k++) {
15294                                                                TResultColumn column = rowList.getColumnList().getResultColumn(k);
15295                                                                if (column.getFieldAttr() == null)
15296                                                                        continue;
15297                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel,
15298                                                                                column.getFieldAttr(), true);
15299
15300                                                                columnsInExpr visitor = new columnsInExpr();
15301                                                                column.getExpr().inOrderTraverse(visitor);
15302                                                                List<TObjectName> objectNames = visitor.getObjectNames();
15303                                                                List<TParseTreeNode> functions = visitor.getFunctions();
15304                                                                List<TParseTreeNode> constants = visitor.getConstants();
15305                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15306
15307                                                                if (functions != null && !functions.isEmpty()) {
15308                                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
15309                                                                }
15310                                                                if (subquerys != null && !subquerys.isEmpty()) {
15311                                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
15312                                                                }
15313                                                                if (objectNames != null && !objectNames.isEmpty()) {
15314                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
15315                                                                }
15316                                                                if (constants != null && !constants.isEmpty()) {
15317                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
15318                                                                                        functions);
15319                                                                }
15320                                                        }
15321                                                }
15322                                        } else {
15323                                                if(table.getTableType() == ETableSource.pivoted_table) {
15324                                                        continue;
15325                                                }
15326                                                if (table.getTableType() == ETableSource.rowList) {
15327                                                        List<TResultColumnList> rowList = table.getValueClause().getRows();
15328                                                        
15329                                                        QueryTable tableModel = modelFactory.createQueryTable(table);
15330                                                        TAliasClause aliasClause = table.getAliasClause();
15331                                                        if (aliasClause != null && aliasClause.getColumns() != null) {
15332                                                                for (TObjectName column : aliasClause.getColumns()) {
15333                                                                        modelFactory.createResultColumn(tableModel, column, true);
15334                                                                }       
15335                                                        } else {        
15336                                                                int columnCount = rowList.get(0).size();
15337                                                                for (int j = 1; j <= columnCount; j++) {
15338                                                                        TObjectName columnName = new TObjectName();
15339                                                                        columnName.setString("column" + j);
15340                                                                        modelFactory.createResultColumn(tableModel, columnName, true);
15341                                                                }
15342                                                        }
15343                                                        tableModel.setDetermined(true);
15344                                                        
15345                                                        for (TResultColumnList resultColumnList : rowList) {
15346                                                                for (int j = 0; j < resultColumnList.size(); j++) {
15347                                                                        TResultColumn resultColumn = resultColumnList.getResultColumn(j);
15348                                                                        analyzeValueColumn(tableModel.getColumns().get(j), resultColumn, EffectType.select);
15349                                                                }
15350                                                        }
15351                                                        
15352                                                } else {
15353                                                        Table tableModel = modelFactory.createTable(table);
15354                                                        for (int j = 0; j < table.getLinkedColumns().size(); j++) {
15355                                                                TObjectName object = table.getLinkedColumns().getObjectName(j);
15356
15357                                                                if (object.getDbObjectType() == EDbObjectType.variable) {
15358                                                                        continue;
15359                                                                }
15360
15361                                                                if (object.getColumnNameOnly().startsWith("@")
15362                                                                                && (option.getVendor() == EDbVendor.dbvmssql
15363                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
15364                                                                        continue;
15365                                                                }
15366
15367                                                                if (object.getColumnNameOnly().startsWith(":")
15368                                                                                && (option.getVendor() == EDbVendor.dbvhana
15369                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
15370                                                                        continue;
15371                                                                }
15372
15373                                                                if (isBuiltInFunctionName(object) && isFromFunction(object)) {
15374                                                                        continue;
15375                                                                }
15376
15377                                                                if (!"*".equals(getColumnName(object))) {
15378                                                                        if (isStructColumn(object)) {
15379
15380                                                                        } else {
15381                                                                                if (pivotedTable != null) {
15382                                                                                        ResultColumn resultColumn = getPivotedTableColumn(pivotedTable, object);
15383                                                                                        if (resultColumn != null) {
15384                                                                                                continue;
15385                                                                                        }
15386                                                                                }
15387                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object,
15388                                                                                                false);
15389                                                                                if(tableColumn == null) {
15390                                                                                        continue;
15391                                                                                }
15392                                                                                if (table.getUnnestClause() != null
15393                                                                                                && table.getUnnestClause().getArrayExpr() != null) {
15394                                                                                        columnsInExpr visitor = new columnsInExpr();
15395                                                                                        table.getUnnestClause().getArrayExpr().inOrderTraverse(visitor);
15396
15397                                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
15398                                                                                        List<TParseTreeNode> functions = visitor.getFunctions();
15399
15400                                                                                        if (functions != null && !functions.isEmpty()) {
15401                                                                                                analyzeFunctionDataFlowRelation(tableColumn, functions,
15402                                                                                                                EffectType.select);
15403
15404                                                                                        }
15405
15406                                                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15407                                                                                        if (subquerys != null && !subquerys.isEmpty()) {
15408                                                                                                analyzeSubqueryDataFlowRelation(tableColumn, subquerys,
15409                                                                                                                EffectType.select);
15410                                                                                        }
15411
15412                                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select,
15413                                                                                                        functions);
15414
15415                                                                                        List<TParseTreeNode> constants = visitor.getConstants();
15416                                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
15417                                                                                                        functions);
15418                                                                                }
15419                                                                        }
15420                                                                } else {
15421                                                                        boolean flag = false;
15422                                                                        for (TObjectName column : table.getLinkedColumns()) {
15423                                                                                if ("*".equals(getColumnName(column))) {
15424                                                                                        continue;
15425                                                                                }
15426                                                                                if (column.getLocation() != ESqlClause.where
15427                                                                                                && column.getLocation() != ESqlClause.joinCondition) {
15428                                                                                        flag = true;
15429                                                                                }
15430                                                                        }
15431                                                                        if (!flag) {
15432                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object,
15433                                                                                                false);
15434                                                                                if (tableColumn != null && !tableModel.hasSQLEnv()) {
15435                                                                                        tableColumn.setShowStar(true);
15436                                                                                }
15437                                                                        }
15438                                                                }
15439
15440                                                        }
15441                                                }
15442                                        }
15443                                }
15444                                else {
15445                                        modelFactory.createTable(table);
15446                                }
15447                        }
15448
15449                        if (pivotedTable!=null) {
15450                                for (TJoin join : stmt.getJoins()) {
15451                                        if (join.getTable() != null && join.getTable().getPivotedTable() != null) {
15452                                                if (isUnPivotedTable(join.getTable().getPivotedTable())) {
15453                                                        analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable());
15454                                                } else {
15455                                                        analyzePivotedTable(stmt, join.getTable().getPivotedTable());
15456                                                }
15457                                                stmtStack.pop();
15458                                                return;
15459                                        }
15460                                }
15461                        }
15462
15463                        if (!stmt.isCombinedQuery()) {
15464                                Object queryModel = modelManager.getModel(stmt.getResultColumnList());
15465
15466                                if (queryModel == null) {
15467                                        TSelectSqlStatement parentStmt = getParentSetSelectStmt(stmt);
15468                                        if (isTopResultSet(stmt) || parentStmt == null) {
15469                                                ResultSet resultSetModel = modelFactory.createResultSet(stmt,
15470                                                                isTopResultSet(stmt) && isShowTopSelectResultSet() && stmt.getIntoClause() == null);
15471
15472                                                createPseudoImpactRelation(stmt, resultSetModel, EffectType.select);
15473
15474                                                boolean isDetermined = true;
15475                                                Map<String, AtomicInteger> keyMap = new HashMap<String, AtomicInteger>();
15476                                                Set<String> columnNames = new HashSet<String>();
15477                                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
15478                                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
15479
15480                                                        if (column.getExpr().getComparisonType() == EComparisonType.equals
15481                                                                        && column.getExpr().getLeftOperand().getObjectOperand() != null) {
15482                                                                TObjectName columnObject = column.getExpr().getLeftOperand().getObjectOperand();
15483
15484                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15485                                                                                columnObject);
15486                                                                if (columnObject.getDbObjectType() == EDbObjectType.variable) {
15487                                                                        Table variable = modelManager
15488                                                                                        .getTableByName(DlineageUtil.getTableFullName(columnObject.toString()));
15489                                                                        if (variable != null) {
15490                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15491                                                                                relation.setEffectType(EffectType.select);
15492                                                                                TableColumn columnModel = variable.getColumns().get(0);
15493                                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel));
15494                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
15495                                                                        } else {
15496                                                                                variable = modelFactory.createVariable(columnObject);
15497                                                                                variable.setCreateTable(true);
15498                                                                                variable.setSubType(SubType.record);
15499                                                                                TObjectName variableProperties = new TObjectName();
15500                                                                                variableProperties.setString("*");
15501                                                                                TableColumn variableProperty = modelFactory.createTableColumn(variable,
15502                                                                                                variableProperties, true);
15503                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15504                                                                                relation.setEffectType(EffectType.select);
15505                                                                                relation.setTarget(new TableColumnRelationshipElement(variableProperty));
15506                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
15507                                                                        }
15508                                                                }
15509
15510                                                                columnsInExpr visitor = new columnsInExpr();
15511                                                                column.getExpr().getRightOperand().inOrderTraverse(visitor);
15512
15513                                                                List<TObjectName> objectNames = visitor.getObjectNames();
15514                                                                List<TParseTreeNode> functions = visitor.getFunctions();
15515
15516                                                                if (functions != null && !functions.isEmpty()) {
15517                                                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.select);
15518
15519                                                                }
15520
15521                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15522                                                                if (subquerys != null && !subquerys.isEmpty()) {
15523                                                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
15524                                                                }
15525
15526                                                                analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
15527
15528                                                                List<TParseTreeNode> constants = visitor.getConstants();
15529                                                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
15530                                                        } else {
15531                                                                if (column.getFieldAttr() != null && isStructColumn(column.getFieldAttr())) {
15532                                                                        Table table = modelFactory.createTable(column.getFieldAttr().getSourceTable());
15533                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
15534                                                                                TObjectName columnName = new TObjectName();
15535                                                                                if (table.getColumns().get(j).getName().equals(table.getAlias())) {
15536                                                                                        if (!SQLUtil.isEmpty(column.getColumnAlias())) {
15537                                                                                                columnName.setString(column.getColumnAlias());
15538                                                                                        } else {
15539                                                                                                columnName.setString(table.getColumns().get(j).getName());
15540                                                                                        }
15541                                                                                } else {
15542                                                                                        columnName.setString(
15543                                                                                                        table.getAlias() + "." + table.getColumns().get(j).getName());
15544                                                                                }
15545                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15546                                                                                                columnName);
15547                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
15548                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
15549                                                                                relationship.addSource(
15550                                                                                                new TableColumnRelationshipElement(table.getColumns().get(j)));
15551                                                                        }
15552                                                                } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.struct_t) {
15553                                                                        Function function = (Function) createFunction(column.getExpr().getFunctionCall());
15554                                                                        String functionName = getResultSetName(function);
15555                                                                        for (int j = 0; j < function.getColumns().size(); j++) {
15556                                                                                TObjectName columnName = new TObjectName();
15557                                                                                if (column.getAliasClause() != null) {
15558                                                                                        columnName.setString(column.getAliasClause() + "."
15559                                                                                                        + function.getColumns().get(j).getName());
15560                                                                                }
15561                                                                                else {
15562                                                                                        columnName.setString(functionName + "."
15563                                                                                                        + function.getColumns().get(j).getName());
15564                                                                                }
15565                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15566                                                                                                columnName);
15567                                                                                resultColumn.setStruct(true);
15568                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
15569                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
15570                                                                                relationship.addSource(
15571                                                                                                new ResultColumnRelationshipElement(function.getColumns().get(j)));
15572                                                                        }
15573                                                                } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.array_t) {
15574                                                                        Function function = (Function) createFunction(column.getExpr().getFunctionCall());
15575                                                                        String functionName = getResultSetName(function);
15576                                                                        for (int j = 0; j < function.getColumns().size(); j++) {
15577                                                                                TObjectName columnName = new TObjectName();
15578                                                                                if (column.getAliasClause() != null) {
15579                                                                                        columnName.setString(column.getAliasClause() + "."
15580                                                                                                        + getColumnNameOnly(function.getColumns().get(j).getName()));
15581                                                                                }
15582                                                                                else {
15583                                                                                        columnName.setString(functionName + "."
15584                                                                                                        + getColumnNameOnly(function.getColumns().get(j).getName()));
15585                                                                                }
15586                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15587                                                                                                columnName);
15588                                                                                resultColumn.setStruct(true);
15589                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
15590                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
15591                                                                                relationship.addSource(
15592                                                                                                new ResultColumnRelationshipElement(function.getColumns().get(j)));
15593                                                                        }
15594                                                                } else if (column.getExpr().getExprList() != null && column.getExpr().getExpressionType() == EExpressionType.array_t) {
15595                                                                        if(column.getExpr().getObjectOperand()!=null) {
15596                                                                                TObjectName exprColumnName = column.getExpr().getObjectOperand();
15597                                                                                Table table = modelFactory.createTable(exprColumnName.getSourceTable());
15598                                                                                for (int z = 0; z < table.getColumns().size(); z++) {
15599                                                                                        TableColumn tableColumn = table.getColumns().get(z);
15600                                                                                        if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) {
15601                                                                                                TObjectName columnName = new TObjectName();
15602                                                                                                if (column.getAliasClause() != null) {
15603                                                                                                        columnName.setString(column.getAliasClause().toString());
15604                                                                                                } else {
15605                                                                                                        columnName
15606                                                                                                                        .setString(getColumnNameOnly(columnName.toString()));
15607                                                                                                }
15608                                                                                                ResultColumn resultColumn = modelFactory
15609                                                                                                                .createResultColumn(resultSetModel, columnName);
15610                                                                                                resultColumn.setStruct(true);
15611                                                                                                DataFlowRelationship relationship = modelFactory
15612                                                                                                                .createDataFlowRelation();
15613                                                                                                relationship.setTarget(
15614                                                                                                                new ResultColumnRelationshipElement(resultColumn));
15615                                                                                                relationship.addSource(new TableColumnRelationshipElement(
15616                                                                                                                tableColumn));
15617                                                                                        }
15618                                                                                }
15619                                                                        }
15620                                                                        else {
15621                                                                                for (int j = 0; j < column.getExpr().getExprList().size(); j++) {
15622                                                                                        TExpression expression = column.getExpr().getExprList().getExpression(j);
15623                                                                                        if(expression.getExpressionType() == EExpressionType.function_t) {
15624                                                                                                Function function = (Function)createFunction(expression.getFunctionCall());
15625                                                                                                String functionName = getResultSetName(function);
15626                                                                                                if (function != null && function.getColumns() != null) {
15627                                                                                                        for (int x = 0; x < function.getColumns().size(); x++) {
15628                                                                                                                TObjectName columnName = new TObjectName();
15629//                                                                                                              if (column.getAliasClause() != null) {
15630//                                                                                                                      columnName.setString(column.getAliasClause() + ".array."
15631//                                                                                                                                      + getColumnNameOnly(
15632//                                                                                                                                                      function.getColumns().get(x).getName()));
15633//                                                                                                              } else {
15634//                                                                                                                      columnName.setString(
15635//                                                                                                                                      functionName + ".array." + getColumnNameOnly(
15636//                                                                                                                                                      function.getColumns().get(x).getName()));
15637//                                                                                                              }
15638                                                                                                                if (column.getAliasClause() != null) {
15639                                                                                                                        columnName.setString(column.getAliasClause() + "."
15640                                                                                                                                        + getColumnNameOnly(
15641                                                                                                                                        function.getColumns().get(x).getName()));
15642                                                                                                                } else {
15643                                                                                                                        columnName.setString(
15644                                                                                                                                        functionName + "." + getColumnNameOnly(
15645                                                                                                                                                        function.getColumns().get(x).getName()));
15646                                                                                                                }
15647                                                                                                                ResultColumn resultColumn = modelFactory
15648                                                                                                                                .createResultColumn(resultSetModel, columnName);
15649                                                                                                                resultColumn.setStruct(true);
15650                                                                                                                DataFlowRelationship relationship = modelFactory
15651                                                                                                                                .createDataFlowRelation();
15652                                                                                                                relationship.setTarget(
15653                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
15654                                                                                                                relationship.addSource(new ResultColumnRelationshipElement(
15655                                                                                                                                function.getColumns().get(x)));
15656                                                                                                        }
15657                                                                                                }
15658                                                                                        }
15659                                                                                        else if(expression.getExpressionType() == EExpressionType.simple_object_name_t) {
15660                                                                                                TObjectName exprColumnName = expression.getObjectOperand();
15661                                                                                                Table table = modelFactory.createTable(exprColumnName.getSourceTable());
15662                                                                                                for (int z = 0; z < table.getColumns().size(); z++) {
15663                                                                                                        TableColumn tableColumn = table.getColumns().get(z);
15664                                                                                                        if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) {
15665                                                                                                                TObjectName columnName = new TObjectName();
15666                                                                                                                if (column.getAliasClause() != null) {
15667                                                                                                                        columnName.setString(column.getAliasClause().toString());
15668                                                                                                                } else {
15669                                                                                                                        columnName
15670                                                                                                                                        .setString(getColumnNameOnly(columnName.toString()));
15671                                                                                                                }
15672                                                                                                                ResultColumn resultColumn = modelFactory
15673                                                                                                                                .createResultColumn(resultSetModel, columnName);
15674                                                                                                                resultColumn.setStruct(true);
15675                                                                                                                DataFlowRelationship relationship = modelFactory
15676                                                                                                                                .createDataFlowRelation();
15677                                                                                                                relationship.setTarget(
15678                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
15679                                                                                                                relationship.addSource(new TableColumnRelationshipElement(
15680                                                                                                                                tableColumn));
15681                                                                                                        }
15682                                                                                                }
15683                                                                                        }
15684                                                                                }
15685                                                                        }
15686                                                                } else {
15687                                                                        if ("*".equals(column.getColumnNameOnly())) {
15688                                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
15689                                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
15690                                                                                if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) {
15691                                                                                        for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) {
15692                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
15693                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
15694                                                                                        }
15695                                                                                }
15696                                                                                
15697                                                                                TObjectName columnObject = column.getFieldAttr();
15698                                                                                List<TTable> sourceTables = columnObject.getSourceTableList();
15699                                                                                if (sourceTables != null && !sourceTables.isEmpty()) {
15700                                                                                        boolean[] determine = new boolean[sourceTables.size()];
15701                                                                                        for (int k = 0; k < sourceTables.size(); k++) {
15702                                                                                                TTable sourceTable = sourceTables.get(k);
15703                                                                                                Object tableModel = modelManager.getModel(sourceTable);
15704                                                                                                if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
15705                                                                                                        Table table = (Table) tableModel;
15706                                                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
15707                                                                                                                TableColumn tableColumn = table.getColumns().get(j);
15708                                                                                                                if (column.getExceptColumnList() != null) {
15709                                                                                                                        boolean except = false;
15710                                                                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
15711                                                                                                                                if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) {
15712                                                                                                                                        except = true;
15713                                                                                                                                        break;
15714                                                                                                                                }
15715                                                                                                                        }
15716                                                                                                                        if (!except && tableColumn.isStruct()) {
15717                                                                                                                                List<String> names = SQLUtil
15718                                                                                                                                                .parseNames(tableColumn.getName());
15719                                                                                                                                for (String name : names) {
15720                                                                                                                                        for (TObjectName objectName : column
15721                                                                                                                                                        .getExceptColumnList()) {
15722                                                                                                                                                if (getColumnName(objectName.toString())
15723                                                                                                                                                                .equals(getColumnName(name))) {
15724                                                                                                                                                        except = true;
15725                                                                                                                                                        break;
15726                                                                                                                                                }
15727                                                                                                                                        }
15728                                                                                                                                        if (except) {
15729                                                                                                                                                break;
15730                                                                                                                                        }
15731                                                                                                                                }
15732                                                                                                                        }
15733                                                                                                                        if(except){
15734                                                                                                                                continue;
15735                                                                                                                        }
15736                                                                                                                }
15737                                                                                                                
15738                                                                                                                if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
15739                                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
15740                                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
15741                                                                                                                        Transform transform = new Transform();
15742                                                                                                                        transform.setType(Transform.EXPRESSION);
15743                                                                                                                        TObjectName expression = new TObjectName();
15744                                                                                                                        expression.setString(expr.first);
15745                                                                                                                transform.setCode(expression);
15746                                                                                                                        resultColumn.setTransform(transform);
15747                                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
15748                                                                                                                }
15749                                                                                                                else {
15750                                                                                                                        String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName());
15751                                                                                                                        //bigquery
15752                                                                                                                        boolean exist = false;
15753                                                                                                                        if (!columnName.matches("(?i)f\\d+_")) {
15754                                                                                                                                if (!keyMap.containsKey(columnName)) {
15755                                                                                                                                        keyMap.put(columnName, new AtomicInteger(0));
15756                                                                                                                                } else {
15757                                                                                                                                        while (columnNames.contains(columnName)) {
15758                                                                                                                                                if(columnName.indexOf("*") == -1 && stmt.toString().matches("(?is).*using\\s*\\(\\s*"+columnName+"\\s*\\).*")) {
15759                                                                                                                                                        exist = true;
15760                                                                                                                                                        break;
15761                                                                                                                                                } else if (keyMap.containsKey(columnName)) {
15762                                                                                                                                                        int index = keyMap.get(columnName)
15763                                                                                                                                                                        .incrementAndGet();
15764                                                                                                                                                        columnName = columnName + index;
15765                                                                                                                                                }
15766                                                                                                                                        }
15767                                                                                                                                }
15768                                                                                                                                columnNames.add(columnName);
15769                                                                                                                        }
15770                                                                                                                        if (exist) {
15771                                                                                                                                String targetColumn = columnName;
15772                                                                                                                                DataFlowRelationship relation = modelFactory
15773                                                                                                                                                .createDataFlowRelation();
15774                                                                                                                                relation.setEffectType(EffectType.select);
15775                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(
15776                                                                                                                                                resultSetModel.getColumns().stream()
15777                                                                                                                                                                .filter(t -> t.getName()
15778                                                                                                                                                                                .equalsIgnoreCase(targetColumn))
15779                                                                                                                                                                .findFirst().get()));
15780                                                                                                                                relation.addSource(new TableColumnRelationshipElement(
15781                                                                                                                                                tableColumn));
15782                                                                                                                                continue;
15783                                                                                                                        }
15784                                                                                                                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName())
15785                                                                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) {
15786                                                                                                                                columnName = tableColumn.getName();
15787                                                                                                                        }
15788                                                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName);
15789                                                                                                                        resultColumn.setStruct(tableColumn.isStruct());
15790                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15791                                                                                                                        relation.setEffectType(EffectType.select);
15792                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15793                                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
15794                                                                                                                }
15795                                                                                                        }
15796                                                                                                        determine[k] = true;
15797                                                                                                        continue;
15798                                                                                                }
15799                                                                                                else if (tableModel instanceof ResultSet && ((ResultSet) tableModel).isDetermined()) {
15800                                                                                                        ResultSet table = (ResultSet) tableModel;
15801                                                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
15802                                                                                                                ResultColumn tableColumn = table.getColumns().get(j);
15803                                                                                                                if (column.getExceptColumnList() != null) {
15804                                                                                                                        boolean except = false;
15805                                                                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
15806                                                                                                                                if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) {
15807                                                                                                                                        except = true;
15808                                                                                                                                        break;
15809                                                                                                                                }
15810                                                                                                                        }
15811                                                                                                                        if (!except && tableColumn.isStruct()) {
15812                                                                                                                                List<String> names = SQLUtil
15813                                                                                                                                                .parseNames(tableColumn.getName());
15814                                                                                                                                for (String name : names) {
15815                                                                                                                                        for (TObjectName objectName : column
15816                                                                                                                                                        .getExceptColumnList()) {
15817                                                                                                                                                if (getColumnName(objectName.toString())
15818                                                                                                                                                                .equals(getColumnName(name))) {
15819                                                                                                                                                        except = true;
15820                                                                                                                                                        break;
15821                                                                                                                                                }
15822                                                                                                                                        }
15823                                                                                                                                        if (except) {
15824                                                                                                                                                break;
15825                                                                                                                                        }
15826                                                                                                                                }
15827                                                                                                                        }
15828                                                                                                                        if(except){
15829                                                                                                                                continue;
15830                                                                                                                        }
15831                                                                                                                }
15832                                                                                                                if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
15833                                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
15834                                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
15835                                                                                                                        Transform transform = new Transform();
15836                                                                                                                        transform.setType(Transform.EXPRESSION);
15837                                                                                                                        TObjectName expression = new TObjectName();
15838                                                                                                                        expression.setString(expr.first);
15839                                                                                                                transform.setCode(expression);
15840                                                                                                                        resultColumn.setTransform(transform);
15841                                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
15842                                                                                                                }
15843                                                                                                                else if(tableColumn.getRefColumnName()!=null) {
15844                                                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, tableColumn.getRefColumnName());
15845                                                                                                                        if(tableColumn.isStruct()) {
15846                                                                                                                                resultColumn.setStruct(true);
15847                                                                                                                        }
15848                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15849                                                                                                                        relation.setEffectType(EffectType.select);
15850                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15851                                                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15852                                                                                                                }
15853                                                                                                                else {
15854                                                                                                                        String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName());
15855                                                                                                                        //bigquery
15856                                                                                                                        if (!columnName.matches("(?i)f\\d+_")) {
15857                                                                                                                                if (!keyMap.containsKey(columnName)) {
15858                                                                                                                                        keyMap.put(columnName, new AtomicInteger(0));
15859                                                                                                                                } else {
15860                                                                                                                                        while (columnNames.contains(columnName)) {
15861                                                                                                                                                int index = keyMap.get(columnName)
15862                                                                                                                                                                .incrementAndGet();
15863                                                                                                                                                columnName = columnName + index;
15864                                                                                                                                        }
15865                                                                                                                                }
15866                                                                                                                                columnNames.add(columnName);
15867                                                                                                                        }
15868                                                                                                                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName())
15869                                                                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) {
15870                                                                                                                                columnName = tableColumn.getName();
15871                                                                                                                        }
15872                                                                                                                        if (modelManager.getModel(column) instanceof ResultColumn) {
15873                                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15874                                                                                                                                relation.setEffectType(EffectType.select);
15875                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement((ResultColumn)modelManager.getModel(column)));
15876                                                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15877                                                                                                                        }
15878                                                                                                                        else {
15879                                                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName);
15880                                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15881                                                                                                                                relation.setEffectType(EffectType.select);
15882                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15883                                                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15884                                                                                                                        }
15885                                                                                                                }
15886                                                                                                        }
15887                                                                                                        determine[k] = true;
15888                                                                                                        continue;
15889                                                                                                }
15890                                                                                                else {
15891                                                                                                        ResultColumn resultColumn = modelFactory
15892                                                                                                                        .createResultColumn(resultSetModel, column);
15893                                                                                                        if (tableModel instanceof Function) {
15894                                                                                                
15895                                                                                                        } else {
15896                                                                                                                TObjectName[] columns = modelManager
15897                                                                                                                                .getTableColumns(sourceTable);
15898                                                                                                                for (int j = 0; j < columns.length; j++) {
15899                                                                                                                        TObjectName columnName = columns[j];
15900                                                                                                                        if (columnName == null
15901                                                                                                                                        || "*".equals(getColumnName(columnName))) {
15902                                                                                                                                continue;
15903                                                                                                                        }
15904                                                                                                                        if (isStructColumn(columnName)) {
15905                                                                                                                                continue;
15906                                                                                                                        }
15907
15908                                                                                                                        resultColumn.bindStarLinkColumn(columnName);
15909                                                                                                                        if (column.getExceptColumnList() != null) {
15910                                                                                                                                for (TObjectName objectName : column
15911                                                                                                                                                .getExceptColumnList()) {
15912                                                                                                                                        resultColumn.unbindStarLinkColumn(objectName);
15913                                                                                                                                }
15914                                                                                                                        }
15915                                                                                                                }
15916                                                                                                                if (tableModel instanceof ResultSet) {
15917                                                                                                                        ResultSet queryTable = (ResultSet) tableModel;
15918                                                                                                                        if (!containStarColumn(queryTable)) {
15919                                                                                                                                resultColumn.setShowStar(false);
15920                                                                                                                        }
15921                                                                                                                }
15922                                                                                                                if (tableModel instanceof Table) {
15923                                                                                                                        Table table = (Table) tableModel;
15924                                                                                                                        if (table.isCreateTable()) {
15925                                                                                                                                resultColumn.setShowStar(false);
15926                                                                                                                        }
15927                                                                                                                }
15928                                                                                                        }
15929                                                                                                }
15930                                                                                        }
15931                                                                                        if(!Arrays.toString(determine).contains("false")) {
15932                                                                                                continue;
15933                                                                                        }
15934                                                                                } else {
15935                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
15936                                                                                        TTableList tables = stmt.getTables();
15937                                                                                        for (int k = 0; k < tables.size(); k++) {
15938                                                                                                TTable table = tables.getTable(k);
15939                                                                                                TObjectName[] columns = modelManager.getTableColumns(table);
15940                                                                                                for (int j = 0; j < columns.length; j++) {
15941                                                                                                        TObjectName columnName = columns[j];
15942                                                                                                        if (columnName == null) {
15943                                                                                                                continue;
15944                                                                                                        }
15945                                                                                                        if ("*".equals(getColumnName(columnName))) {
15946                                                                                                                if (modelManager.getModel(table) instanceof Table) {
15947                                                                                                                        Table tableModel = (Table) modelManager.getModel(table);
15948                                                                                                                        if (tableModel != null
15949                                                                                                                                        && !tableModel.getColumns().isEmpty()) {
15950                                                                                                                                for (TableColumn item : tableModel.getColumns()) {
15951                                                                                                                                        resultColumn
15952                                                                                                                                                        .bindStarLinkColumn(item.getColumnObject());
15953                                                                                                                                        if (table.getSubquery() == null
15954                                                                                                                                                        && table.getCTE() == null
15955                                                                                                                                                        && !tableModel.isCreateTable()) {
15956                                                                                                                                                resultColumn.setShowStar(true);
15957                                                                                                                                        }
15958                                                                                                                                }
15959                                                                                                                        }
15960                                                                                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
15961                                                                                                                        QueryTable tableModel = (QueryTable) modelManager
15962                                                                                                                                        .getModel(table);
15963                                                                                                                        if (tableModel != null
15964                                                                                                                                        && !tableModel.getColumns().isEmpty()) {
15965                                                                                                                                for (ResultColumn item : tableModel.getColumns()) {
15966                                                                                                                                        if (item.hasStarLinkColumn()) {
15967                                                                                                                                                for (TObjectName starLinkColumn : item
15968                                                                                                                                                                .getStarLinkColumnList()) {
15969                                                                                                                                                        resultColumn
15970                                                                                                                                                                        .bindStarLinkColumn(starLinkColumn);
15971                                                                                                                                                }
15972                                                                                                                                        } else if (item
15973                                                                                                                                                        .getColumnObject() instanceof TObjectName) {
15974                                                                                                                                                resultColumn.bindStarLinkColumn(
15975                                                                                                                                                                (TObjectName) item.getColumnObject());
15976                                                                                                                                        } else if (item
15977                                                                                                                                                        .getColumnObject() instanceof TResultColumn) {
15978                                                                                                                                                TResultColumn queryTableColumn = (TResultColumn) item
15979                                                                                                                                                                .getColumnObject();
15980                                                                                                                                                TObjectName tableColumnObject = queryTableColumn
15981                                                                                                                                                                .getFieldAttr();
15982                                                                                                                                                if (tableColumnObject != null) {
15983                                                                                                                                                        resultColumn.bindStarLinkColumn(
15984                                                                                                                                                                        tableColumnObject);
15985                                                                                                                                                } else if (queryTableColumn
15986                                                                                                                                                                .getAliasClause() != null) {
15987                                                                                                                                                        resultColumn.bindStarLinkColumn(
15988                                                                                                                                                                        queryTableColumn.getAliasClause()
15989                                                                                                                                                                                        .getAliasName());
15990                                                                                                                                                }
15991                                                                                                                                        }
15992                                                                                                                                }
15993                                                                                                                        }
15994                                                                                                                }
15995                                                                                                                continue;
15996                                                                                                        }
15997                                                                                                        resultColumn.bindStarLinkColumn(columnName);
15998                                                                                                }
15999                                                                                        }
16000                                                                                }
16001                                                                                isDetermined = false;
16002                                                                        }
16003                                                                        else {
16004                                                                                if(column.getAliasClause()!=null && column.getAliasClause().getColumns()!=null) {
16005                                                                                        for(TObjectName aliasColumn: column.getAliasClause().getColumns()) {
16006                                                                                                modelFactory.createResultColumn(resultSetModel, aliasColumn);
16007                                                                                        }
16008                                                                                }
16009                                                                                else {
16010                                                                                        modelFactory.createResultColumn(resultSetModel, column);
16011                                                                                }
16012                                                                        }
16013                                                                        analyzeResultColumn(column, EffectType.select);
16014                                                                }
16015                                                        }
16016                                                }
16017                                                if (isDetermined) {
16018                                                        resultSetModel.setDetermined(isDetermined);
16019                                                }
16020                                        }
16021
16022                                        TSelectSqlStatement parent = getParentSetSelectStmt(stmt);
16023                                        if (parent != null && parent.getSetOperatorType() != ESetOperatorType.none) {
16024                                                ResultSet resultSetModel = modelFactory.createResultSet(stmt, false);
16025                                                if(queryModel == null) {
16026                                                        queryModel = resultSetModel;
16027                                                } 
16028
16029                                                createPseudoImpactRelation(stmt, resultSetModel, EffectType.select);
16030
16031                                                boolean isDetermined = true;
16032                                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
16033                                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
16034                                                        if ("*".equals(column.getColumnNameOnly())) {
16035                                                                
16036                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
16037                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
16038                                                                if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) {
16039                                                                        for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) {
16040                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
16041                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
16042                                                                        }
16043                                                                }
16044                                                                
16045                                                                TObjectName columnObject = column.getFieldAttr();
16046                                                                TTable sourceTable = columnObject.getSourceTable();
16047                                                                if (sourceTable != null) {
16048                                                                        Object tableModel = modelManager.getModel(sourceTable);
16049                                                                        if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
16050                                                                                Table table = (Table) tableModel;
16051                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16052                                                                                        TableColumn tableColumn = table.getColumns().get(j);
16053                                                                                        if (column.getExceptColumnList() != null) {
16054                                                                                                boolean except = false;
16055                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16056                                                                                                        if (getColumnName(objectName.toString())
16057                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16058                                                                                                                except = true;
16059                                                                                                                break;
16060                                                                                                        }
16061                                                                                                }
16062                                                                                                if (!except && tableColumn.isStruct()) {
16063                                                                                                        List<String> names = SQLUtil
16064                                                                                                                        .parseNames(tableColumn.getName());
16065                                                                                                        for (String name : names) {
16066                                                                                                                for (TObjectName objectName : column
16067                                                                                                                                .getExceptColumnList()) {
16068                                                                                                                        if (getColumnName(objectName.toString())
16069                                                                                                                                        .equals(getColumnName(name))) {
16070                                                                                                                                except = true;
16071                                                                                                                                break;
16072                                                                                                                        }
16073                                                                                                                }
16074                                                                                                                if (except) {
16075                                                                                                                        break;
16076                                                                                                                }
16077                                                                                                        }
16078                                                                                                }
16079                                                                                                if (except) {
16080                                                                                                        continue;
16081                                                                                                }
16082                                                                                        }
16083                                                                                        
16084                                                                                        if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
16085                                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
16086                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
16087                                                                                                Transform transform = new Transform();
16088                                                                                                transform.setType(Transform.EXPRESSION);
16089                                                                                                TObjectName expression = new TObjectName();
16090                                                                                                expression.setString(expr.first);
16091                                                                                        transform.setCode(expression);
16092                                                                                                resultColumn.setTransform(transform);
16093                                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
16094                                                                                        }
16095                                                                                        else {
16096                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16097                                                                                                                resultSetModel, column, tableColumn.getName());
16098                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16099                                                                                                relation.setEffectType(EffectType.select);
16100                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16101                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16102                                                                                        }
16103                                                                                }
16104                                                                                continue;
16105                                                                        } else if (tableModel instanceof ResultSet
16106                                                                                        && ((ResultSet) tableModel).isDetermined()) {
16107                                                                                ResultSet table = (ResultSet) tableModel;
16108                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16109                                                                                        ResultColumn tableColumn = table.getColumns().get(j);
16110                                                                                        if (column.getExceptColumnList() != null) {
16111                                                                                                boolean except = false;
16112                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16113                                                                                                        if (getColumnName(objectName.toString())
16114                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16115                                                                                                                except = true;
16116                                                                                                                break;
16117                                                                                                        }
16118                                                                                                }
16119                                                                                                if (!except && tableColumn.isStruct()) {
16120                                                                                                        List<String> names = SQLUtil
16121                                                                                                                        .parseNames(tableColumn.getName());
16122                                                                                                        for (String name : names) {
16123                                                                                                                for (TObjectName objectName : column
16124                                                                                                                                .getExceptColumnList()) {
16125                                                                                                                        if (getColumnName(objectName.toString())
16126                                                                                                                                        .equals(getColumnName(name))) {
16127                                                                                                                                except = true;
16128                                                                                                                                break;
16129                                                                                                                        }
16130                                                                                                                }
16131                                                                                                                if (except) {
16132                                                                                                                        break;
16133                                                                                                                }
16134                                                                                                        }
16135                                                                                                }
16136                                                                                                if (except) {
16137                                                                                                        continue;
16138                                                                                                }
16139                                                                                        }
16140                                                                                        
16141                                                                                        if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
16142                                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
16143                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
16144                                                                                                Transform transform = new Transform();
16145                                                                                                transform.setType(Transform.EXPRESSION);
16146                                                                                                TObjectName expression = new TObjectName();
16147                                                                                                expression.setString(expr.first);
16148                                                                                        transform.setCode(expression);
16149                                                                                                resultColumn.setTransform(transform);
16150                                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
16151                                                                                        }
16152                                                                                        else if (tableColumn.getRefColumnName() != null) {
16153                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16154                                                                                                                (ResultSet)queryModel, column, tableColumn.getRefColumnName());
16155                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16156                                                                                                relation.setEffectType(EffectType.select);
16157                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16158                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16159                                                                                        } else {
16160                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16161                                                                                                                resultSetModel, column, tableColumn.getName());
16162                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16163                                                                                                relation.setEffectType(EffectType.select);
16164                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16165                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16166                                                                                        }
16167                                                                                }
16168                                                                                continue;
16169                                                                        }
16170                                                                        else {
16171                                                                                isDetermined = false;
16172                                                                        }
16173                                                                }
16174                                                                
16175                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
16176                                                                
16177                                                                if (columnObject.getTableToken() != null && sourceTable != null) {
16178                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
16179                                                                        for (int j = 0; j < columns.length; j++) {
16180                                                                                TObjectName columnName = columns[j];
16181                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
16182                                                                                        continue;
16183                                                                                }
16184                                                                                resultColumn.bindStarLinkColumn(columnName);
16185                                                                        }
16186
16187                                                                        if (modelManager.getModel(sourceTable) instanceof Table) {
16188                                                                                Table tableModel = (Table) modelManager.getModel(sourceTable);
16189                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16190                                                                                        for (TableColumn item : tableModel.getColumns()) {
16191                                                                                                if ("*".equals(getColumnName(item.getColumnObject()))) {
16192                                                                                                        continue;
16193                                                                                                }
16194                                                                                                resultColumn.bindStarLinkColumn(item.getColumnObject());
16195                                                                                        }
16196                                                                                }
16197                                                                        } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
16198                                                                                QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
16199                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16200                                                                                        for (ResultColumn item : tableModel.getColumns()) {
16201                                                                                                if (item.hasStarLinkColumn()) {
16202                                                                                                        for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
16203                                                                                                                if ("*".equals(getColumnName(starLinkColumn))) {
16204                                                                                                                        continue;
16205                                                                                                                }
16206                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
16207                                                                                                        }
16208                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
16209                                                                                                        TObjectName starLinkColumn = (TObjectName) item.getColumnObject();
16210                                                                                                        if ("*".equals(getColumnName(starLinkColumn))) {
16211                                                                                                                continue;
16212                                                                                                        }
16213                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
16214                                                                                                }
16215                                                                                        }
16216                                                                                }
16217                                                                        }
16218
16219                                                                } else {
16220                                                                        TTableList tables = stmt.getTables();
16221                                                                        for (int k = 0; k < tables.size(); k++) {
16222                                                                                TTable table = tables.getTable(k);
16223                                                                                TObjectName[] columns = modelManager.getTableColumns(table);
16224                                                                                for (int j = 0; j < columns.length; j++) {
16225                                                                                        TObjectName columnName = columns[j];
16226                                                                                        if (columnName == null) {
16227                                                                                                continue;
16228                                                                                        }
16229                                                                                        if ("*".equals(getColumnName(columnName))) {
16230                                                                                                if (modelManager.getModel(table) instanceof Table) {
16231                                                                                                        Table tableModel = (Table) modelManager.getModel(table);
16232                                                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16233                                                                                                                for (TableColumn item : tableModel.getColumns()) {
16234                                                                                                                        resultColumn.bindStarLinkColumn(item.getColumnObject());
16235                                                                                                                }
16236                                                                                                        }
16237                                                                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
16238                                                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(table);
16239                                                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16240                                                                                                                for (ResultColumn item : tableModel.getColumns()) {
16241                                                                                                                        if (item.hasStarLinkColumn()) {
16242                                                                                                                                for (TObjectName starLinkColumn : item
16243                                                                                                                                                .getStarLinkColumnList()) {
16244                                                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
16245                                                                                                                                }
16246                                                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
16247                                                                                                                                resultColumn.bindStarLinkColumn(
16248                                                                                                                                                (TObjectName) item.getColumnObject());
16249                                                                                                                        } else if (item
16250                                                                                                                                        .getColumnObject() instanceof TResultColumn) {
16251                                                                                                                                TResultColumn queryTableColumn = (TResultColumn) item
16252                                                                                                                                                .getColumnObject();
16253                                                                                                                                TObjectName tableColumnObject = queryTableColumn
16254                                                                                                                                                .getFieldAttr();
16255                                                                                                                                if (tableColumnObject != null) {
16256                                                                                                                                        resultColumn.bindStarLinkColumn(tableColumnObject);
16257                                                                                                                                } else if (queryTableColumn.getAliasClause() != null) {
16258                                                                                                                                        resultColumn.bindStarLinkColumn(queryTableColumn
16259                                                                                                                                                        .getAliasClause().getAliasName());
16260                                                                                                                                }
16261                                                                                                                        }
16262                                                                                                                }
16263                                                                                                        }
16264                                                                                                }
16265
16266                                                                                                continue;
16267                                                                                        }
16268                                                                                        resultColumn.bindStarLinkColumn(columnName);
16269                                                                                }
16270                                                                        }
16271                                                                }
16272                                                        }
16273                                                        else {
16274                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
16275                                                        }
16276                                                        analyzeResultColumn(column, EffectType.select);
16277
16278                                                }
16279                                                
16280                                                resultSetModel.setDetermined(isDetermined);
16281                                        }
16282                                } else {
16283                                        for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
16284                                                TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
16285
16286                                                if (!(queryModel instanceof ResultSet)) {
16287                                                        continue;
16288                                                }
16289                                                
16290                                                ResultSet resultSetModel = (ResultSet)queryModel;
16291                                                        
16292                                                if ("*".equals(column.getColumnNameOnly())) {
16293                                                        TObjectName columnObject = column.getFieldAttr();
16294                                                        TTable sourceTable = columnObject.getSourceTable();
16295                                                        if (column.toString().indexOf(".") == -1 && stmt.getTables().size() > 1) {
16296                                                                sourceTable = null;
16297                                                        }
16298                                                        if (sourceTable != null) {
16299                                                                {
16300                                                                        Object tableModel = modelManager.getModel(sourceTable);
16301                                                                        if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
16302                                                                                Table table = (Table) tableModel;
16303                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16304                                                                                        TableColumn tableColumn = table.getColumns().get(j);
16305                                                                                        if (column.getExceptColumnList() != null) {
16306                                                                                                boolean except = false;
16307                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16308                                                                                                        if (getColumnName(objectName.toString())
16309                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16310                                                                                                                except = true;
16311                                                                                                                break;
16312                                                                                                        }
16313                                                                                                }
16314                                                                                                if (!except && tableColumn.isStruct()) {
16315                                                                                                        List<String> names = SQLUtil
16316                                                                                                                        .parseNames(tableColumn.getName());
16317                                                                                                        for (String name : names) {
16318                                                                                                                for (TObjectName objectName : column
16319                                                                                                                                .getExceptColumnList()) {
16320                                                                                                                        if (getColumnName(objectName.toString())
16321                                                                                                                                        .equals(getColumnName(name))) {
16322                                                                                                                                except = true;
16323                                                                                                                                break;
16324                                                                                                                        }
16325                                                                                                                }
16326                                                                                                                if (except) {
16327                                                                                                                        break;
16328                                                                                                                }
16329                                                                                                        }
16330                                                                                                }
16331                                                                                                if (except) {
16332                                                                                                        continue;
16333                                                                                                }
16334                                                                                        }
16335                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(
16336                                                                                                        resultSetModel, column, tableColumn.getName());
16337                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16338                                                                                        relation.setEffectType(EffectType.select);
16339                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16340                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
16341                                                                                }
16342                                                                                if(stmt.getResultColumnList().size() == 1) {
16343                                                                                        resultSetModel.setDetermined(true);
16344                                                                                }
16345                                                                                else {
16346                                                                                        int starCount = 0;
16347                                                                                        for (int j = 0; j < stmt.getResultColumnList().size(); j++) {
16348                                                                                                if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly()
16349                                                                                                                .endsWith("*")) {
16350                                                                                                        starCount += 1;
16351                                                                                                }
16352                                                                                        }
16353                                                                                        if (starCount <= 1) {
16354                                                                                                resultSetModel.setDetermined(true);
16355                                                                                        }
16356                                                                                }
16357                                                                                continue;
16358                                                                        } else if (tableModel instanceof ResultSet
16359                                                                                        && ((ResultSet) tableModel).isDetermined()) {
16360                                                                                ResultSet table = (ResultSet) tableModel;
16361                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16362                                                                                        ResultColumn tableColumn = table.getColumns().get(j);
16363                                                                                        if (column.getExceptColumnList() != null) {
16364                                                                                                boolean except = false;
16365                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16366                                                                                                        if (getColumnName(objectName.toString())
16367                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16368                                                                                                                except = true;
16369                                                                                                                break;
16370                                                                                                        }
16371                                                                                                }
16372                                                                                                if (!except && tableColumn.isStruct()) {
16373                                                                                                        List<String> names = SQLUtil
16374                                                                                                                        .parseNames(tableColumn.getName());
16375                                                                                                        for (String name : names) {
16376                                                                                                                for (TObjectName objectName : column
16377                                                                                                                                .getExceptColumnList()) {
16378                                                                                                                        if (getColumnName(objectName.toString())
16379                                                                                                                                        .equals(getColumnName(name))) {
16380                                                                                                                                except = true;
16381                                                                                                                                break;
16382                                                                                                                        }
16383                                                                                                                }
16384                                                                                                                if (except) {
16385                                                                                                                        break;
16386                                                                                                                }
16387                                                                                                        }
16388                                                                                                }
16389                                                                                                if (except) {
16390                                                                                                        continue;
16391                                                                                                }
16392                                                                                        }
16393                                                                                        if (tableColumn.getRefColumnName() != null) {
16394                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16395                                                                                                                (ResultSet)queryModel, column, tableColumn.getRefColumnName());
16396                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16397                                                                                                relation.setEffectType(EffectType.select);
16398                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16399                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16400                                                                                        } else {
16401                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16402                                                                                                                resultSetModel, column, tableColumn.getName());
16403                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16404                                                                                                relation.setEffectType(EffectType.select);
16405                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16406                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16407                                                                                        }
16408                                                                                }
16409                                                                                if(stmt.getResultColumnList().size() == 1) {
16410                                                                                        resultSetModel.setDetermined(true);
16411                                                                                }
16412                                                                                else {
16413                                                                                        int starCount = 0;
16414                                                                                        for (int j = 0; j < stmt.getResultColumnList().size(); j++) {
16415                                                                                                if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly()
16416                                                                                                                .endsWith("*")) {
16417                                                                                                        starCount += 1;
16418                                                                                                }
16419                                                                                        }
16420                                                                                        if (starCount <= 1) {
16421                                                                                                resultSetModel.setDetermined(true);
16422                                                                                        }
16423                                                                                }
16424                                                                                continue;
16425                                                                        }
16426                                                                }
16427                                                                
16428                                                                ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
16429                                                                if (modelManager.getModel(sourceTable) instanceof Table) {
16430                                                                        Table tableModel = (Table) modelManager.getModel(sourceTable);
16431                                                                        if (tableModel != null) {
16432                                                                                modelFactory.createTableColumn(tableModel, columnObject, false);
16433                                                                        }
16434                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
16435                                                                        for (int j = 0; j < columns.length; j++) {
16436                                                                                TObjectName columnName = columns[j];
16437                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
16438                                                                                        continue;
16439                                                                                }
16440                                                                                resultColumn.bindStarLinkColumn(columnName);
16441                                                                        }
16442
16443                                                                        if (tableModel.getColumns() != null) {
16444                                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
16445                                                                                        TableColumn tableColumn = tableModel.getColumns().get(j);
16446                                                                                        TObjectName columnName = tableColumn.getColumnObject();
16447                                                                                        if (columnName == null || "*".equals(getColumnName(columnName))) {
16448                                                                                                continue;
16449                                                                                        }
16450                                                                                        resultColumn.bindStarLinkColumn(columnName);
16451                                                                                }
16452                                                                        }
16453                                                                } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
16454                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
16455                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16456                                                                                for (ResultColumn item : tableModel.getColumns()) {
16457                                                                                        if (item.hasStarLinkColumn()) {
16458                                                                                                for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
16459                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
16460                                                                                                }
16461                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
16462                                                                                                resultColumn.bindStarLinkColumn((TObjectName) item.getColumnObject());
16463                                                                                        } else if (item.getColumnObject() instanceof TResultColumn) {
16464                                                                                                TResultColumn queryTableColumn = (TResultColumn) item.getColumnObject();
16465                                                                                                TObjectName tableColumnObject = queryTableColumn.getFieldAttr();
16466                                                                                                if (tableColumnObject != null) {
16467                                                                                                        resultColumn.bindStarLinkColumn(tableColumnObject);
16468                                                                                                } else if (queryTableColumn.getAliasClause() != null) {
16469                                                                                                        resultColumn.bindStarLinkColumn(
16470                                                                                                                        queryTableColumn.getAliasClause().getAliasName());
16471                                                                                                }
16472                                                                                        }
16473                                                                                }
16474                                                                        }
16475                                                                }
16476                                                        } else {
16477                                                                ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
16478                                                                TTableList tables = stmt.getTables();
16479                                                                for (int k = 0; k < tables.size(); k++) {
16480                                                                        TTable table = tables.getTable(k);
16481                                                                        TObjectName[] columns = modelManager.getTableColumns(table);
16482                                                                        for (int j = 0; j < columns.length; j++) {
16483                                                                                TObjectName columnName = columns[j];
16484                                                                                if (columnName == null) {
16485                                                                                        continue;
16486                                                                                }
16487                                                                                if ("*".equals(getColumnName(columnName))) {
16488                                                                                        if (modelManager.getModel(table) instanceof Table) {
16489                                                                                                Table tableModel = (Table) modelManager.getModel(table);
16490                                                                                                if (tableModel != null) {
16491                                                                                                        modelFactory.createTableColumn(tableModel, columnName, false);
16492                                                                                                }
16493                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16494                                                                                                        for (int z = 0; z < tableModel.getColumns().size(); z++) {
16495                                                                                                                resultColumn.bindStarLinkColumn(
16496                                                                                                                                tableModel.getColumns().get(z).getColumnObject());
16497                                                                                                        }
16498                                                                                                }
16499                                                                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
16500                                                                                                QueryTable tableModel = (QueryTable) modelManager.getModel(table);
16501                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16502                                                                                                        for (ResultColumn item : tableModel.getColumns()) {
16503                                                                                                                if (item.hasStarLinkColumn()) {
16504                                                                                                                        for (TObjectName starLinkColumn : item
16505                                                                                                                                        .getStarLinkColumnList()) {
16506                                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
16507                                                                                                                        }
16508                                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
16509                                                                                                                        resultColumn.bindStarLinkColumn(
16510                                                                                                                                        (TObjectName) item.getColumnObject());
16511                                                                                                                } else if (item.getColumnObject() instanceof TResultColumn) {
16512                                                                                                                        TResultColumn queryTableColumn = (TResultColumn) item
16513                                                                                                                                        .getColumnObject();
16514                                                                                                                        TObjectName tableColumnObject = queryTableColumn
16515                                                                                                                                        .getFieldAttr();
16516                                                                                                                        if (tableColumnObject != null) {
16517                                                                                                                                resultColumn.bindStarLinkColumn(tableColumnObject);
16518                                                                                                                        } else if (queryTableColumn.getAliasClause() != null) {
16519                                                                                                                                resultColumn.bindStarLinkColumn(queryTableColumn
16520                                                                                                                                                .getAliasClause().getAliasName());
16521                                                                                                                        }
16522                                                                                                                }
16523                                                                                                        }
16524                                                                                                }
16525                                                                                        }
16526                                                                                        continue;
16527                                                                                }
16528                                                                                resultColumn.bindStarLinkColumn(columnName);
16529                                                                        }
16530                                                                }
16531                                                        }
16532                                                }
16533                                                else {
16534                                                        ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
16535                                                }
16536                                                
16537                                                analyzeResultColumn(column, EffectType.select);
16538
16539                                        }
16540                                        
16541                                        if (queryModel instanceof ResultSet) {
16542                                                boolean isDetermined = true;
16543                                                ResultSet resultSet = (ResultSet) queryModel;
16544                                                for (ResultColumn column : resultSet.getColumns()) {
16545                                                        if (column.getName().endsWith("*")) {
16546                                                                isDetermined = false;
16547                                                                break;
16548                                                        }
16549                                                }
16550                                                if (isDetermined) {
16551                                                        resultSet.setDetermined(isDetermined);
16552                                                }
16553                                        }
16554                                }
16555                        }
16556
16557                
16558                        analyzeSelectIntoClause(stmt);
16559                
16560
16561                        if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
16562                                for (int i = 0; i < stmt.getJoins().size(); i++) {
16563                                        TJoin join = stmt.getJoins().getJoin(i);
16564                                        ResultSet topResultSet = (ResultSet) modelManager.getModel(stmt);
16565                                        if (join.getJoinItems() != null && join.getJoinItems().size() > 0) {
16566                                                for (int k = 0; k < join.getJoinItems().size(); k++) {
16567                                                        TTable table = join.getJoinItems().getJoinItem(k).getTable();
16568                                                        if (table != null && table.getSubquery() != null) {
16569                                                                
16570                                                                ResultSet joinResultSet = (ResultSet) modelManager.getModel(table.getSubquery());
16571                                                                for (int x = 0; x < joinResultSet.getColumns().size(); x++) {
16572                                                                        ResultColumn sourceColumn = joinResultSet.getColumns().get(x);
16573                                                                        ResultColumn resultColumn = matchResultColumn(topResultSet.getColumns(),
16574                                                                                        sourceColumn);
16575                                                                        if (resultColumn != null
16576                                                                                        && resultColumn.getColumnObject() instanceof TResultColumn) {
16577                                                                                TResultColumn column = (TResultColumn) resultColumn.getColumnObject();
16578                                                                                if (column.getAliasClause() == null && column.getFieldAttr() != null) {
16579                                                                                        TObjectName resultObject = column.getFieldAttr();
16580                                                                                        if (resultObject.getSourceTable() == null
16581                                                                                                        || resultObject.getSourceTable().equals(table)) {
16582                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
16583                                                                                                                .createDataFlowRelation();
16584                                                                                                combinedQueryRelation.setEffectType(EffectType.select);
16585                                                                                                combinedQueryRelation
16586                                                                                                                .setTarget(new ResultColumnRelationshipElement(resultColumn));
16587                                                                                                combinedQueryRelation
16588                                                                                                                .addSource(new ResultColumnRelationshipElement(sourceColumn));
16589                                                                                        }
16590                                                                                }
16591                                                                        }
16592                                                                }
16593                                                        }
16594                                                        
16595                                                        if(join.getJoinItems().getJoinItem(k).getJoin()!=null) {
16596                                                                analyzeJoin(join.getJoinItems().getJoinItem(k).getJoin(), EffectType.select);
16597                                                        }
16598                                                }
16599                                        }
16600                                        analyzeJoin(join, EffectType.select);
16601                                }
16602                        }
16603
16604                        if (stmt.getWhereClause() != null) {
16605                                TExpression expr = stmt.getWhereClause().getCondition();
16606                                if (expr != null) {
16607                                        analyzeFilterCondition(null, expr, null, JoinClauseType.where, EffectType.select);
16608                                }
16609                        }
16610
16611                        stmtStack.pop();
16612                }
16613        }
16614
16615        protected boolean isTopResultSet(TSelectSqlStatement stmt) {
16616                TCustomSqlStatement parent = stmt.getParentStmt();
16617                if (parent == null)
16618                        return true;
16619                if (parent instanceof TMssqlReturn) {
16620                        return true;
16621                }
16622                if (parent instanceof TReturnStmt) {
16623                        return true;
16624                }
16625                if (parent instanceof TCommonBlock) {
16626                        TCommonBlock block = (TCommonBlock) parent;
16627                        if (block.getStatements() != null) {
16628                                for (int i = 0; i < block.getStatements().size(); i++) {
16629                                        TCustomSqlStatement child = block.getStatements().get(i);
16630                                        if(stmt == child) {
16631                                                return true;
16632                                        }
16633                                }
16634                        }
16635                }
16636                if (parent instanceof TMssqlBlock) {
16637                        TMssqlBlock block = (TMssqlBlock) parent;
16638                        if (block.getStatements() != null) {
16639                                for (int i = 0; i < block.getStatements().size(); i++) {
16640                                        TCustomSqlStatement child = block.getStatements().get(i);
16641                                        if(stmt == child) {
16642                                                return true;
16643                                        }
16644                                }
16645                        }
16646                }
16647                if (parent instanceof TStoredProcedureSqlStatement) {
16648                        TStoredProcedureSqlStatement block = (TStoredProcedureSqlStatement) parent;
16649                        if (block.getStatements() != null) {
16650                                for (int i = 0; i < block.getStatements().size(); i++) {
16651                                        TCustomSqlStatement child = block.getStatements().get(i);
16652                                        if(child == stmt) {
16653                                                return true;
16654                                        }
16655                                        if (child instanceof TReturnStmt) {
16656                                                TReturnStmt returnStmt = (TReturnStmt) child;
16657                                                if (returnStmt.getStatements() != null) {
16658                                                        for (int j = 0; j < returnStmt.getStatements().size(); j++) {
16659                                                                TCustomSqlStatement child1 = returnStmt.getStatements().get(j);
16660                                                                if(child1 == stmt) {
16661                                                                        return true;
16662                                                                }
16663                                                        }
16664                                                }
16665                                        }
16666                                        if (child instanceof TMssqlReturn) {
16667                                                TMssqlReturn returnStmt = (TMssqlReturn) child;
16668                                                if (returnStmt.getStatements() != null) {
16669                                                        for (int j = 0; j < returnStmt.getStatements().size(); j++) {
16670                                                                TCustomSqlStatement child1 = returnStmt.getStatements().get(j);
16671                                                                if(child1 == stmt) {
16672                                                                        return true;
16673                                                                }
16674                                                        }
16675                                                }
16676                                        }
16677                                }
16678                        }
16679                }
16680                return false;
16681        }
16682
16683        protected void analyzeTableSubquery(TTable table) {
16684                if(table.getSubquery()!=null) {
16685                        QueryTable queryTable = modelFactory.createQueryTable(table);
16686                        TSelectSqlStatement subquery = table.getSubquery();
16687                        analyzeSelectStmt(subquery);
16688
16689                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
16690
16691                        if (resultSetModel != null && resultSetModel != queryTable
16692                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
16693                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
16694                                impactRelation.setEffectType(EffectType.select);
16695                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
16696                                                resultSetModel.getRelationRows()));
16697                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
16698                                                queryTable.getRelationRows()));
16699                        }
16700
16701                        if (resultSetModel != null && resultSetModel != queryTable
16702                                        && queryTable.getTableObject().getAliasClause() != null
16703                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
16704                                for (int j = 0; j < queryTable.getColumns().size()
16705                                                && j < resultSetModel.getColumns().size(); j++) {
16706                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
16707                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
16708
16709                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
16710                                        queryRalation.setEffectType(EffectType.select);
16711                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
16712                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
16713                                }
16714                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
16715                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
16716                                                .getModel(subquery);
16717                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
16718                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
16719                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
16720                                                        sourceColumn);
16721                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
16722                                                targetColumn.bindStarLinkColumn(starLinkColumn);
16723                                        }
16724                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
16725                                        selectSetRalation.setEffectType(EffectType.select);
16726                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
16727                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
16728                                }
16729                        }
16730                }
16731        }
16732
16733        private ResultColumn getPivotedTableColumn(TPivotedTable pivotedTable, TObjectName columnName) {
16734                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
16735                if (pivotedTable.getPivotClause() != null) {
16736                        pivotClauses.add(pivotedTable.getPivotClause());
16737                }
16738                if (pivotedTable.getPivotClauseList() != null) {
16739                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
16740                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
16741                        }
16742                }
16743                for (TPivotClause clause : pivotClauses) {
16744                        Object model = modelManager.getModel(clause);
16745                        if (model instanceof PivotedTable) {
16746                                PivotedTable pivotedTableModel = (PivotedTable) model;
16747                                if (pivotedTableModel.getColumns() != null) {
16748                                        for (ResultColumn column : pivotedTableModel.getColumns()) {
16749                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
16750                                                                getColumnName(SQLUtil.trimColumnStringQuote(column.getName())))) {
16751                                                        return column;
16752                                                }
16753                                        }
16754                                }
16755                        }
16756                }
16757                return null;
16758        }
16759
16760        private void analyzeHiveTransformClause(TSelectSqlStatement stmt, THiveTransformClause transformClause) {
16761                Table mapSourceTable = null;
16762                QueryTable mapQueryTable = null;
16763                if(stmt.getTables()!=null) {
16764                        for(int i=0;i<stmt.getTables().size();i++) {
16765                                TTable table = stmt.getTables().getTable(i);
16766                                if (table.getSubquery() != null) {
16767                                        if (transformClause.getTransformType() == ETransformType.ettReduce) {
16768                                                mapQueryTable = modelFactory.createQueryTable(table);
16769                                        }
16770                                        analyzeSelectStmt(table.getSubquery());
16771                                }
16772                                else {
16773                                        mapSourceTable = modelFactory.createTable(table);
16774                                }
16775                        }
16776                }
16777                
16778                if (transformClause.getTransformType() == ETransformType.ettReduce) {
16779                        modelFactory.createResultSet(stmt, false);
16780                }
16781                
16782                List<TableColumn> mapTableColumns = new ArrayList<TableColumn>();
16783                List<ResultColumn> mapResultSetColumns = new ArrayList<ResultColumn>();
16784                List<ResultColumn> redueResultSetColumns = new ArrayList<ResultColumn>();
16785                
16786                if(transformClause.getExpressionList()!=null) {
16787                        for(TExpression expression: transformClause.getExpressionList()) {
16788                                if(expression.getObjectOperand()!=null) {
16789                                        if (transformClause.getTransformType() == ETransformType.ettMap || transformClause.getTransformType() == ETransformType.ettSelect) {
16790                                                if (mapSourceTable != null) {
16791                                                        TableColumn tableColumn = modelFactory.createTableColumn(mapSourceTable,
16792                                                                        expression.getObjectOperand(), false);
16793                                                        if (tableColumn != null) {
16794                                                                mapTableColumns.add(tableColumn);
16795                                                        }
16796                                                }
16797                                        }
16798                                        else if (transformClause.getTransformType() == ETransformType.ettReduce) {
16799                                                if (mapQueryTable != null) {
16800                                                        ResultColumn resultColumn = modelFactory.createResultColumn(mapQueryTable,
16801                                                                        expression.getObjectOperand(), false);
16802                                                        if (resultColumn != null) {
16803                                                                mapResultSetColumns.add(resultColumn);
16804                                                        }
16805                                                }
16806                                        }
16807                                }
16808                        }
16809                }
16810                
16811                if (transformClause.getAliasClause() != null) {
16812                        Object model = modelManager.getModel(stmt);
16813                        if (model instanceof ResultSet) {
16814                                ResultSet result = (ResultSet) model;
16815                                if (result!=null && transformClause.getAliasClause().getColumns() != null) {
16816                                        for (TObjectName column : transformClause.getAliasClause().getColumns()) {
16817                                                ResultColumn resultColumn = modelFactory.createResultColumn(result, column);
16818                                                if (resultColumn != null) {
16819                                                        if (transformClause.getTransformType() == ETransformType.ettMap 
16820                                                                        || transformClause.getTransformType() == ETransformType.ettSelect) {
16821                                                                mapResultSetColumns.add(resultColumn);
16822                                                        }
16823                                                        else if (transformClause.getTransformType() == ETransformType.ettReduce) {
16824                                                                redueResultSetColumns.add(resultColumn);
16825                                                        }
16826                                                }
16827                                        }
16828                                }
16829                        }
16830                }
16831                
16832                if (transformClause.getTransformType() == ETransformType.ettMap 
16833                                || transformClause.getTransformType() == ETransformType.ettSelect) {
16834                        if (!mapTableColumns.isEmpty() && !mapResultSetColumns.isEmpty()) {
16835                                for (ResultColumn resultColumn : mapResultSetColumns) {
16836                                        for (TableColumn tableColumn : mapTableColumns) {
16837                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16838                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16839                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16840                                                relation.setEffectType(EffectType.select);
16841                                        }
16842                                }
16843                        }
16844                }
16845                else if (transformClause.getTransformType() == ETransformType.ettReduce) {
16846                        if (!redueResultSetColumns.isEmpty() && !mapResultSetColumns.isEmpty()) {
16847                                for (ResultColumn reduceResultColumn : redueResultSetColumns) {
16848                                        for (ResultColumn mapResultColumn : mapResultSetColumns) {
16849                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16850                                                relation.setTarget(new ResultColumnRelationshipElement(reduceResultColumn));
16851                                                relation.addSource(new ResultColumnRelationshipElement(mapResultColumn));
16852                                                relation.setEffectType(EffectType.select);
16853                                        }
16854                                }
16855                        }
16856                }
16857        }
16858
16859        protected boolean isStructColumn(TObjectName columnName) {
16860                return columnName.getSourceTable() != null && columnName.getSourceTable().getAliasClause() != null
16861                                && columnName.getSourceTable().getUnnestClause() != null
16862                                && DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
16863                                                getColumnName(columnName.getSourceTable().getAliasClause().getAliasName()));
16864        }
16865
16866        private TObjectName getObjectName(ResultColumn column) {
16867                if (column.getColumnObject() instanceof TResultColumn) {
16868                        TResultColumn resultColumn = (TResultColumn) column.getColumnObject();
16869                        if (resultColumn.getAliasClause() != null && resultColumn.getAliasClause().getAliasName() != null) {
16870                                return resultColumn.getAliasClause().getAliasName();
16871                        }
16872                        if (resultColumn.getFieldAttr() != null) {
16873                                return resultColumn.getFieldAttr();
16874                        }
16875                        if (resultColumn.getExpr() != null
16876                                        && resultColumn.getExpr().getExpressionType() == EExpressionType.simple_object_name_t) {
16877                                return resultColumn.getExpr().getObjectOperand();
16878                        }
16879                } else if (column.getColumnObject() instanceof TObjectName) {
16880                        return (TObjectName) column.getColumnObject();
16881                }
16882                return null;
16883        }
16884
16885        private boolean isShowTopSelectResultSet() {
16886                if (option.isSimpleOutput() && !option.isSimpleShowTopSelectResultSet())
16887                        return false;
16888                return true;
16889        }
16890
16891        private void analyzeSelectIntoClause(TSelectSqlStatement stmt) {
16892                if (stmt.getParentStmt() instanceof TSelectSqlStatement) {
16893                        return;
16894                }
16895                
16896                TableColumn oracleIntoTableColumn = null;
16897                
16898                TIntoClause intoClause = stmt.getIntoClause();
16899                
16900                TSelectSqlStatement leftStmt = DlineageUtil.getLeftStmt(stmt);
16901                
16902                if (intoClause == null && leftStmt != null) {
16903                        intoClause = leftStmt.getIntoClause();
16904                }
16905                
16906                if (intoClause != null) {
16907                        List<TObjectName> tableNames = new ArrayList<TObjectName>();
16908                        if (intoClause.getExprList() != null) {
16909                                for (int j = 0; j < intoClause.getExprList().size(); j++) {
16910                                        TObjectName tableName = intoClause.getExprList().getExpression(j).getObjectOperand();
16911                                        if (tableName != null) {
16912                                                if (tableName.toString().startsWith(":") && option.getVendor() == EDbVendor.dbvoracle
16913                                                                && tableName.getDbObjectType() == EDbObjectType.column) {
16914                                                        TObjectName tableAlias = new TObjectName();
16915                                                        tableAlias.setString(tableName.getTableString());
16916                                                        tableNames.add(tableAlias);
16917                                                        TTable sourceTable = tableName.getSourceTable();
16918                                                        Table sourceTableModel = modelFactory.createTable(sourceTable, tableAlias);
16919                                                        oracleIntoTableColumn = modelFactory.createTableColumn(sourceTableModel, tableName, true);
16920                                                } else {
16921                                                        if (tableName != null) {
16922                                                                tableNames.add(tableName);
16923                                                        }
16924                                                }
16925                                        }
16926                                        else if(intoClause.getExprList().getExpression(j).getFunctionCall()!=null) {
16927                                                TObjectName variableName = intoClause.getExprList().getExpression(j).getFunctionCall().getFunctionName();
16928                                                tableNames.add(variableName);
16929                                                Variable variable = modelFactory.createVariable(variableName);
16930                                                variable.setSubType(SubType.record);
16931                                                TObjectName variableProperties = new TObjectName();
16932                                                variableProperties.setString("*");
16933                                                modelFactory.createTableColumn(variable, variableProperties, true);
16934                                        }
16935                                }
16936                        } else if (intoClause.getVariableList() != null) {
16937                                for (int j = 0; j < intoClause.getVariableList().size(); j++) {
16938                                        TObjectName tableName = intoClause.getVariableList().getObjectName(j);
16939                                        if (tableName != null) {
16940                                                tableNames.add(tableName);
16941                                        }
16942                                }
16943                        } else if (intoClause.getIntoName() != null) {
16944                                tableNames.add(intoClause.getIntoName());
16945                        }
16946
16947                        ResultSet queryModel = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
16948                        if (stmt.getSetOperatorType() != ESetOperatorType.none) {
16949                                queryModel = (ResultSet) modelManager.getModel(stmt);
16950                        }
16951                        for (int j = 0; j < tableNames.size(); j++) {
16952                                TObjectName tableName = tableNames.get(j);
16953                                if (tableName.getColumnNameOnly().startsWith("@")
16954                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
16955                                        continue;
16956                                }
16957
16958                                if (tableName.getColumnNameOnly().startsWith(":")
16959                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
16960                                        continue;
16961                                }
16962
16963                                Table tableModel;
16964                                TableColumn variableColumn = null;
16965
16966                                if (tableName.getDbObjectType() == EDbObjectType.variable) {
16967                                        if (tableName.toString().indexOf(".") != -1) {
16968                                                List<String> splits = SQLUtil.parseNames(tableName.toString());
16969                                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
16970                                        } else {
16971                                                tableModel = modelFactory.createVariable(tableName);
16972                                        }
16973                                        if (tableModel.getSubType() == null) {
16974                                                tableModel.setSubType(SubType.record);
16975                                        }
16976                                        if(tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
16977                                                TObjectName variableProperties = new TObjectName();
16978                                                variableProperties.setString("*");
16979                                                variableColumn = modelFactory.createTableColumn(tableModel, variableProperties, true);
16980                                        }
16981                                } else {
16982                                        tableModel = modelFactory.createTableByName(tableName);
16983                                }
16984                                
16985                                if (queryModel instanceof ResultSet && (stmt.getWhereClause() != null || hasJoin(stmt))) {
16986                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
16987                                        impactRelation.setEffectType(EffectType.insert);
16988                                        impactRelation.addSource(
16989                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)queryModel).getRelationRows()));
16990                                        impactRelation.setTarget(
16991                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
16992                                }
16993                                
16994                                Process process = modelFactory.createProcess(stmt);
16995                                tableModel.addProcess(process);
16996                                
16997                                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
16998                                        for (ResultColumn resultColumn : queryModel.getColumns()) {
16999                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17000                                                                resultColumn.getName());
17001
17002                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
17003                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
17004                                                        TSQLSchema schema = sqlenv
17005                                                                        .getSQLSchema(tableModel.getDatabase() + "." + tableModel.getSchema(), true);
17006                                                        if (schema != null) {
17007                                                                TSQLTable tempTable = schema
17008                                                                                .createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
17009                                                                tempTable.addColumn(tableColumn.getName());
17010                                                        }
17011                                                }
17012
17013                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17014                                                relation.setEffectType(EffectType.insert);
17015                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17016                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17017                                                relation.setProcess(process);
17018                                        }
17019                                        
17020                                        tableModel.setDetermined(queryModel.isDetermined());
17021                                        if(queryModel.isDetermined() && DlineageUtil.isTempTable(tableModel, option.getVendor())) {
17022                                                tableModel.setCreateTable(true, false);
17023                                        }
17024                                        return;
17025                                }
17026
17027                                boolean isDetermined = true;
17028                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
17029                                        if (tableNames.size() > 1 && tableName.getDbObjectType() == EDbObjectType.variable) {
17030                                                if (i != j) {
17031                                                        continue;
17032                                                }
17033                                        }
17034                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
17035
17036                                        if ("*".equals(column.getColumnNameOnly()) && column.getFieldAttr() != null
17037                                                        && column.getFieldAttr().getSourceTable() != null) {
17038                                                Object model = modelManager.getModel(column);
17039                                                if(model instanceof LinkedHashMap) {
17040                                                        LinkedHashMap<String, ResultColumn> columns = (LinkedHashMap<String, ResultColumn>)model;
17041                                                        for(String key: columns.keySet()) {
17042                                                                ResultColumn sourceColumn = columns.get(key);
17043                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17044                                                                                sourceColumn.getName());
17045                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17046                                                                relation.setEffectType(EffectType.insert);
17047                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17048                                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
17049                                                                relation.setProcess(process);
17050                                                        }
17051                                                }
17052                                                else if(model instanceof ResultColumn) {
17053                                                        isDetermined = false;
17054                                                        ResultColumn resultColumn = (ResultColumn) model;
17055                                                        List<TObjectName> columns = resultColumn.getStarLinkColumnList();
17056                                                        if (columns.size() > 0) {
17057                                                                for (int k = 0; k < columns.size(); k++) {
17058        
17059                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17060                                                                                        columns.get(k));
17061        
17062                                                                        if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
17063                                                                                        && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
17064                                                                                TSQLSchema schema = sqlenv.getSQLSchema(
17065                                                                                                tableModel.getDatabase() + "." + tableModel.getSchema(), true);
17066                                                                                if (schema != null) {
17067                                                                                        TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
17068                                                                                        tempTable.addColumn(tableColumn.getName());
17069                                                                                }
17070                                                                        }
17071        
17072                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17073                                                                        relation.setEffectType(EffectType.insert);
17074                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17075                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17076                                                                        relation.setProcess(process);
17077                                                                }
17078                                                                if (resultColumn.isShowStar()) {
17079                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17080                                                                                        column.getFieldAttr());
17081                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17082                                                                        relation.setEffectType(EffectType.insert);
17083                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17084                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17085                                                                        relation.setProcess(process);
17086                                                                }
17087                                                        } else {
17088                                                                TObjectName columnObject = column.getFieldAttr();
17089                                                                if (column.getAliasClause() != null) {
17090                                                                        columnObject = column.getAliasClause().getAliasName();
17091                                                                }
17092                                                                if (columnObject != null) {
17093                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17094                                                                                        columnObject);
17095                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17096                                                                        relation.setEffectType(EffectType.insert);
17097                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17098                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17099                                                                        relation.setProcess(process);
17100                                                                } else if (!SQLUtil.isEmpty(column.getColumnAlias())) {
17101                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17102                                                                                        column.getAliasClause().getAliasName());
17103                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17104                                                                        relation.setEffectType(EffectType.insert);
17105                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17106                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17107                                                                        relation.setProcess(process);
17108                                                                }
17109                                                        }
17110                                                }
17111                                        } else {
17112                                                ResultColumn resultColumn = null;
17113
17114                                                if (queryModel instanceof QueryTable) {
17115                                                        resultColumn = (ResultColumn) modelManager.getModel(column);
17116                                                } else if (queryModel instanceof ResultSet) {
17117                                                        resultColumn = (ResultColumn) modelManager.getModel(column);
17118                                                } else {
17119                                                        continue;
17120                                                }
17121
17122                                                if (resultColumn == null && column.getAliasClause() != null) {
17123                                                        resultColumn = (ResultColumn) modelManager.getModel(column.getAliasClause().getAliasName());
17124                                                }
17125
17126                                                if (resultColumn != null) {
17127                                                        TObjectName columnObject = column.getFieldAttr();
17128                                                        if (column.getAliasClause() != null) {
17129                                                                columnObject = column.getAliasClause().getAliasName();
17130                                                        }
17131                                                        TableColumn tableColumn = null;
17132                                                        if (columnObject != null) {
17133                                                                if (tableModel.isVariable()) {
17134                                                                        if (variableColumn != null) {
17135                                                                                tableColumn = variableColumn;
17136                                                                        } else {
17137                                                                                tableColumn = tableModel.getColumns().get(0);
17138                                                                        }
17139                                                                } 
17140                                                                else if (oracleIntoTableColumn != null) {
17141                                                                        tableColumn = oracleIntoTableColumn;
17142                                                                }
17143                                                                else {
17144                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, columnObject);
17145                                                                        if (containStarColumn(queryModel)) {
17146                                                                                tableColumn.notBindStarLinkColumn(true);
17147                                                                        }
17148                                                                }
17149                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17150                                                                relation.setEffectType(EffectType.insert);
17151                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17152                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17153                                                                relation.setProcess(process);
17154                                                        } else if (!SQLUtil.isEmpty(column.getColumnAlias())) {
17155                                                                if (tableModel.isVariable()) {
17156                                                                        if (variableColumn != null) {
17157                                                                                tableColumn = variableColumn;
17158                                                                        } else {
17159                                                                                tableColumn = tableModel.getColumns().get(0);
17160                                                                        }
17161                                                                } else {
17162                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
17163                                                                                        column.getAliasClause().getAliasName());
17164                                                                }
17165                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17166                                                                relation.setEffectType(EffectType.insert);
17167                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17168                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17169                                                                relation.setProcess(process);
17170                                                        } else {
17171                                                                if (tableModel.isVariable()) {
17172                                                                        if (variableColumn != null) {
17173                                                                                tableColumn = variableColumn;
17174                                                                        } else {
17175                                                                                tableColumn = tableModel.getColumns().get(0);
17176                                                                        }
17177                                                                }
17178                                                                if (tableColumn != null) {
17179                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17180                                                                        relation.setEffectType(EffectType.insert);
17181                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17182                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17183                                                                        relation.setProcess(process);
17184                                                                }
17185                                                        }
17186                                                }
17187                                        }
17188                                }
17189                                tableModel.setDetermined(isDetermined);
17190                                if(isDetermined && DlineageUtil.isTempTable(tableModel, option.getVendor())) {
17191                                        tableModel.setCreateTable(true, false);
17192                                }
17193                        }
17194                }
17195        }
17196
17197        private boolean isUnPivotedTable(TPivotedTable pivotedTable) {
17198                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
17199                        return pivotedTable.getPivotClauseList().getElement(0).getType() == TPivotClause.unpivot;
17200                } else {
17201                        TPivotClause pivotClause = pivotedTable.getPivotClause();
17202                        return pivotClause.getType() == TPivotClause.unpivot;
17203                }
17204        }
17205
17206        private void analyzeUnPivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) {
17207                List<Object> tables = new ArrayList<Object>();
17208                Set<Object> pivotedColumns = new HashSet<Object>();
17209                TTable fromTable = pivotedTable.getTableSource();
17210                Object table = modelManager.getModel(fromTable);
17211                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
17212                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
17213                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
17214                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
17215                        }
17216                } else {
17217                        TPivotClause pivotClause = pivotedTable.getPivotClause();
17218                        pivotClauses.add(pivotClause);
17219                }
17220
17221                for (int y = 0; y < pivotClauses.size(); y++) {
17222                        TPivotClause pivotClause = pivotClauses.get(y);
17223                        PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause);
17224                        pivotTable.setUnpivoted(true);
17225
17226                        if (pivotClause.getValueColumnList() != null) {
17227                                for (int j = 0; j < pivotClause.getValueColumnList().size(); j++) {
17228                                        modelFactory.createResultColumn(pivotTable, pivotClause.getValueColumnList().getObjectName(j));
17229                                }
17230                        }
17231                        if (pivotClause.getPivotColumnList() != null) {
17232                                for (int j = 0; j < pivotClause.getPivotColumnList().size(); j++) {
17233                                        modelFactory.createResultColumn(pivotTable, pivotClause.getPivotColumnList().getObjectName(j));
17234                                }
17235                        }
17236                        if (pivotClause.getUnpivotInClause()!=null && pivotClause.getUnpivotInClause().getItems() != null) {
17237                                for (int j = 0; j < pivotClause.getUnpivotInClause().getItems().size(); j++) {
17238                                        TObjectName columnName = pivotClause.getUnpivotInClause().getItems().getElement(j).getColumn();
17239                                        if (columnName != null) {
17240                                                if (table instanceof QueryTable) {
17241                                                        for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
17242                                                                if (getColumnName(columnName)
17243                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17244                                                                        for (ResultColumn resultColumn : pivotTable.getColumns()) {
17245                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17246                                                                                relation.setEffectType(EffectType.select);
17247                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17248                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17249                                                                                pivotedColumns.add(tableColumn);
17250                                                                        }
17251                                                                        break;
17252                                                                }
17253                                                        }
17254                                                } else if (table instanceof Table) {
17255                                                        for (TableColumn tableColumn : ((Table) table).getColumns()) {
17256                                                                if (getColumnName(columnName)
17257                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17258                                                                        for (ResultColumn resultColumn : pivotTable.getColumns()) {
17259                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17260                                                                                relation.setEffectType(EffectType.select);
17261                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17262                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17263                                                                                pivotedColumns.add(tableColumn);
17264                                                                        }
17265                                                                        break;
17266                                                                }
17267                                                        }
17268                                                }
17269                                        } else {
17270                                                TObjectNameList columnNames = pivotClause.getUnpivotInClause().getItems().getElement(j)
17271                                                                .getColumnList();
17272                                                for (TObjectName columnName1 : columnNames) {
17273                                                        if (table instanceof QueryTable) {
17274                                                                for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
17275                                                                        if (getColumnName(columnName1).equals(
17276                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17277                                                                                for (ResultColumn resultColumn : pivotTable.getColumns()) {
17278                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17279                                                                                        relation.setEffectType(EffectType.select);
17280                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17281                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17282                                                                                        pivotedColumns.add(tableColumn);
17283                                                                                }
17284                                                                                break;
17285                                                                        }
17286                                                                }
17287                                                        } else if (table instanceof Table) {
17288                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
17289                                                                        if (getColumnName(columnName1).equals(
17290                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17291                                                                                for (ResultColumn resultColumn : pivotTable.getColumns()) {
17292                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17293                                                                                        relation.setEffectType(EffectType.select);
17294                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17295                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17296                                                                                        pivotedColumns.add(tableColumn);
17297                                                                                }
17298                                                                                break;
17299                                                                        }
17300                                                                }
17301                                                        }
17302                                                }
17303                                        }
17304                                }
17305                        }
17306                        tables.add(pivotTable);
17307                        tables.add(table);
17308                }
17309
17310                ResultSet resultSet = modelFactory.createResultSet(stmt,
17311                                isTopResultSet(stmt) && isShowTopSelectResultSet());
17312                TResultColumnList columnList = stmt.getResultColumnList();
17313                for (int i = 0; i < columnList.size(); i++) {
17314                        TResultColumn column = columnList.getResultColumn(i);
17315                        ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
17316                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
17317                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17318                                if (columnObject.getFieldAttr() != null) {
17319                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
17320                                                resultColumn.setShowStar(false);
17321                                                int index = 0;
17322                                                for (int k = 0; k < tables.size(); k++) {
17323                                                        Object tableItem = tables.get(k);
17324                                                        if (tableItem instanceof ResultSet) {
17325                                                                for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) {
17326                                                                        ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
17327                                                                        if (pivotedColumns.contains(tableColumn)) {
17328                                                                                continue;
17329                                                                        }
17330                                                                        if (tableColumn.getColumnObject() instanceof TObjectName) {
17331                                                                                resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject());
17332                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17333                                                                                relation.setEffectType(EffectType.select);
17334                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17335                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17336                                                                        } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
17337                                                                                if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
17338                                                                                        if (tableColumn.hasStarLinkColumn()) {
17339                                                                                                for (int z = 0; z < tableColumn.getStarLinkColumnList().size(); z++) {
17340                                                                                                        ResultColumn resultColumn1 = modelFactory.createResultColumn(
17341                                                                                                                        (ResultSet) tableItem,
17342                                                                                                                        tableColumn.getStarLinkColumnList().get(z));
17343                                                                                                        DataFlowRelationship relation = modelFactory
17344                                                                                                                        .createDataFlowRelation();
17345                                                                                                        relation.setEffectType(EffectType.select);
17346                                                                                                        relation.setTarget(
17347                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
17348                                                                                                        relation.addSource(
17349                                                                                                                        new ResultColumnRelationshipElement(resultColumn1));
17350                                                                                                        tableColumn.getStarLinkColumns().remove(
17351                                                                                                                        getColumnName(tableColumn.getStarLinkColumnList().get(z)));
17352                                                                                                        z--;
17353                                                                                                }
17354                                                                                        } else {
17355                                                                                                resultColumn.bindStarLinkColumn(
17356                                                                                                                ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr());
17357                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17358                                                                                                relation.setEffectType(EffectType.select);
17359                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr()));
17360                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17361                                                                                        }
17362                                                                                } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) {
17363                                                                                        TExpression expr = ((TResultColumn) tableColumn.getColumnObject())
17364                                                                                                        .getExpr();
17365                                                                                        if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
17366                                                                                                TObjectName columnName = new TObjectName();
17367                                                                                                columnName.setString(expr.toString());
17368                                                                                                resultColumn.bindStarLinkColumn(columnName);
17369                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17370                                                                                                relation.setEffectType(EffectType.select);
17371                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, columnName));
17372                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17373                                                                                        }
17374                                                                                }
17375                                                                        }
17376                                                                }
17377                                                        } else if (tableItem instanceof Table) {
17378                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17379                                                                        if (pivotedColumns.contains(tableColumn)) {
17380                                                                                continue;
17381                                                                        }
17382                                                                        resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(), index);
17383                                                                        index++;
17384                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17385                                                                        relation.setEffectType(EffectType.select);
17386                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17387                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17388                                                                }
17389                                                        }
17390                                                }
17391                                        } else {
17392                                                for (int k = 0; k < tables.size(); k++) {
17393                                                        Object tableItem = tables.get(k);
17394                                                        if (tableItem instanceof ResultSet) {
17395                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
17396                                                                        if (getColumnName(columnObject.getFieldAttr()).equals(
17397                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17398                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17399                                                                                relation.setEffectType(EffectType.select);
17400                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17401                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17402                                                                                break;
17403                                                                        }
17404                                                                }
17405                                                        } else if (tableItem instanceof Table) {
17406                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17407                                                                        if (getColumnName(columnObject.getFieldAttr()).equals(
17408                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17409                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17410                                                                                relation.setEffectType(EffectType.select);
17411                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17412                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17413                                                                                break;
17414                                                                        }
17415                                                                }
17416                                                        }
17417                                                }
17418                                        }
17419                                } else if (columnObject.getExpr() != null) {
17420                                        analyzeResultColumn(column, EffectType.select);
17421                                }
17422                        }
17423                }
17424        }
17425
17426        private void analyzePivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) {
17427                List<Object> tables = new ArrayList<Object>();
17428                Set<Object> pivotedColumns = new HashSet<Object>();
17429                TTable fromTable = pivotedTable.getTableSource();
17430                Object table = modelManager.getModel(fromTable);
17431                if(table == null && fromTable.getSubquery()!=null) {
17432                        table = modelFactory.createQueryTable(fromTable);
17433                        TSelectSqlStatement subquery = fromTable.getSubquery();
17434                        analyzeSelectStmt(subquery);
17435                }
17436                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
17437                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
17438                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
17439                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
17440                        }
17441                } else {
17442                        TPivotClause pivotClause = pivotedTable.getPivotClause();
17443                        pivotClauses.add(pivotClause);
17444                }
17445
17446                for (int y = 0; y < pivotClauses.size(); y++) {
17447                        TPivotClause pivotClause = pivotClauses.get(y);
17448                        List<TFunctionCall> functionCalls = new ArrayList<TFunctionCall>();
17449                        if (pivotClause.getAggregation_function() != null || pivotClause.getAggregation_function_list() != null) {
17450                                if (pivotClause.getAggregation_function() != null) {
17451                                        functionCalls.add((TFunctionCall) pivotClause.getAggregation_function());
17452                                } else if (pivotClause.getAggregation_function_list() != null) {
17453                                        for (int i = 0; i < pivotClause.getAggregation_function_list().size(); i++) {
17454                                                functionCalls.add((TFunctionCall) pivotClause.getAggregation_function_list().getResultColumn(i)
17455                                                                .getExpr().getFunctionCall());
17456                                        }
17457                                }
17458
17459                                if (functionCalls.isEmpty()) {
17460                                        return;
17461                                }
17462
17463                                if (pivotClause.getPivotColumnList() == null) {
17464                                        return;
17465                                }
17466
17467                                if (pivotClause.getPivotInClause() == null) {
17468                                        return;
17469                                }
17470
17471                                for (int x = 0; x < functionCalls.size(); x++) {
17472                                        TFunctionCall functionCall = functionCalls.get(x);
17473                                        Function function = modelFactory.createFunction(functionCall);
17474                                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
17475                                                        ((TFunctionCall) functionCall).getFunctionName());
17476
17477                                        List<TExpression> expressions = new ArrayList<TExpression>();
17478                                        getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall);
17479
17480                                        for (int j = 0; j < expressions.size(); j++) {
17481                                                columnsInExpr visitor = new columnsInExpr();
17482                                                expressions.get(j).inOrderTraverse(visitor);
17483                                                List<TObjectName> objectNames = visitor.getObjectNames();
17484                                                if (objectNames == null) {
17485                                                        continue;
17486                                                }
17487                                                for (TObjectName columnName : objectNames) {
17488                                                        if (table instanceof QueryTable) {
17489                                                                for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) {
17490                                                                        boolean find = false;
17491                                                                        ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i);
17492                                                                        if (tableColumn.hasStarLinkColumn()) {
17493                                                                                for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) {
17494                                                                                        TObjectName objectName = tableColumn.getStarLinkColumnList().get(k);
17495                                                                                        if (getColumnName(columnName).equals(getColumnName(objectName))) {
17496                                                                                                ResultColumn resultColumn = modelFactory
17497                                                                                                                .createResultColumn((QueryTable) table, objectName);
17498                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17499                                                                                                relation.setEffectType(EffectType.select);
17500                                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17501                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17502                                                                                                pivotedColumns.add(resultColumn);
17503                                                                                                tableColumn.getStarLinkColumns()
17504                                                                                                                .remove(DlineageUtil.getColumnName(objectName));
17505                                                                                                find = true;
17506                                                                                                break;
17507                                                                                        }
17508                                                                                }
17509                                                                        } else if (getColumnName(columnName).equals(
17510                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17511                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17512                                                                                relation.setEffectType(EffectType.select);
17513                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17514                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17515                                                                                pivotedColumns.add(tableColumn);
17516                                                                                find = true;
17517                                                                                break;
17518                                                                        } 
17519                                                                        
17520                                                                        if (!find && tableColumn.getName().endsWith("*")) {
17521                                                                                QueryTable queryTable = (QueryTable)table;
17522                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(queryTable, columnName);
17523                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17524                                                                                relation.setEffectType(EffectType.select);
17525                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17526                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17527                                                                                tableColumn.bindStarLinkColumn(columnName);
17528                                                                        }
17529                                                                }
17530                                                        } else if (table instanceof Table) {
17531                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
17532                                                                        if (getColumnName(columnName).equals(
17533                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17534                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17535                                                                                relation.setEffectType(EffectType.select);
17536                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17537                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17538                                                                                pivotedColumns.add(tableColumn);
17539                                                                                break;
17540                                                                        }
17541                                                                }
17542                                                        }
17543                                                }
17544                                        }
17545
17546                                        PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause);
17547                                        pivotTable.setUnpivoted(false);
17548
17549                                        if (pivotClause.getPivotInClause().getItems() != null) {
17550                                                for (int j = 0; j < pivotClause.getPivotInClause().getItems().size(); j++) {
17551                                                        ResultColumn resultColumn = null;
17552                                                        if (pivotClause.getAggregation_function_list() != null
17553                                                                        && pivotClause.getAggregation_function_list().size() > 1) {
17554                                                                TResultColumn functionColumn = pivotClause.getAggregation_function_list()
17555                                                                                .getResultColumn(x);
17556                                                                TObjectName tableColumn = new TObjectName();
17557                                                                if (option.getVendor() == EDbVendor.dbvbigquery) {
17558                                                                        tableColumn.setString(getResultColumnString(functionColumn) + "_"
17559                                                                                        + SQLUtil.trimColumnStringQuote(getResultColumnString(
17560                                                                                                        pivotClause.getPivotInClause().getItems().getResultColumn(j))));
17561                                                                }
17562                                                                else {
17563                                                                        tableColumn.setString(SQLUtil
17564                                                                                        .trimColumnStringQuote(getResultColumnString(
17565                                                                                                        pivotClause.getPivotInClause().getItems().getResultColumn(j)))
17566                                                                                        + "_" + getResultColumnString(functionColumn));
17567                                                                }
17568                                                                resultColumn = modelFactory.createResultColumn(pivotTable, tableColumn);
17569                                                        } else {
17570                                                                resultColumn = modelFactory.createSelectSetResultColumn(pivotTable,
17571                                                                                pivotClause.getPivotInClause().getItems().getResultColumn(j), j);
17572                                                        }
17573                                                        {
17574                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17575                                                                relation.setEffectType(EffectType.select);
17576                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17577                                                                relation.addSource(new ResultColumnRelationshipElement(column));
17578                                                        }
17579                                                        {
17580                                                                for (TObjectName columnName : pivotClause.getPivotColumnList()) {
17581                                                                        if (table instanceof QueryTable) {
17582                                                                                for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) {
17583                                                                                        ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i);
17584                                                                                        if (tableColumn.hasStarLinkColumn()) {
17585                                                                                                for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) {
17586                                                                                                        TObjectName objectName = tableColumn.getStarLinkColumnList().get(k);
17587                                                                                                        if (getColumnName(columnName).equals(getColumnName(objectName))) {
17588                                                                                                                ResultColumn resultColumn1 = modelFactory
17589                                                                                                                                .createResultColumn((QueryTable) table, objectName);
17590                                                                                                                DataFlowRelationship relation = modelFactory
17591                                                                                                                                .createDataFlowRelation();
17592                                                                                                                relation.setEffectType(EffectType.select);
17593                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17594                                                                                                                relation.addSource(
17595                                                                                                                                new ResultColumnRelationshipElement(resultColumn1));
17596                                                                                                                pivotedColumns.add(resultColumn1);
17597                                                                                                                tableColumn.getStarLinkColumns()
17598                                                                                                                                .remove(DlineageUtil.getColumnName(objectName));
17599                                                                                                                break;
17600                                                                                                        }
17601                                                                                                }
17602                                                                                        } else if (getColumnName(columnName).equals(DlineageUtil
17603                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17604                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17605                                                                                                relation.setEffectType(EffectType.select);
17606                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17607                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17608                                                                                                pivotedColumns.add(tableColumn);
17609                                                                                                break;
17610                                                                                        }
17611                                                                                }
17612                                                                        } else if (table instanceof Table) {
17613                                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
17614                                                                                        if (getColumnName(columnName).equals(DlineageUtil
17615                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17616                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17617                                                                                                relation.setEffectType(EffectType.select);
17618                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17619                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17620                                                                                                pivotedColumns.add(tableColumn);
17621                                                                                                break;
17622                                                                                        }
17623                                                                                }
17624                                                                        }
17625                                                                }
17626                                                        }
17627                                                }
17628                                        } else if (pivotClause.getPivotInClause().getSubQuery() != null) {
17629                                                TSelectSqlStatement subquery = pivotClause.getPivotInClause().getSubQuery();
17630                                                analyzeSelectStmt(subquery);
17631                                                ResultSet selectSetResultSetModel = (ResultSet) modelManager.getModel(subquery);
17632                                                for (int j = 0; j < subquery.getResultColumnList().size(); j++) {
17633                                                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(pivotTable,
17634                                                                        subquery.getResultColumnList().getResultColumn(j), j);
17635                                                        {
17636                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17637                                                                relation.setEffectType(EffectType.select);
17638                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17639                                                                relation.addSource(new ResultColumnRelationshipElement(column));
17640                                                                relation.addSource(new ResultColumnRelationshipElement(
17641                                                                                selectSetResultSetModel.getColumns().get(j)));
17642                                                        }
17643                                                        {
17644                                                                for (TObjectName columnName : pivotClause.getPivotColumnList()) {
17645                                                                        if (table instanceof QueryTable) {
17646                                                                                for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
17647                                                                                        if (getColumnName(columnName).equals(DlineageUtil
17648                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17649                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17650                                                                                                relation.setEffectType(EffectType.select);
17651                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17652                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17653                                                                                                pivotedColumns.add(tableColumn);
17654                                                                                                break;
17655                                                                                        }
17656                                                                                }
17657                                                                        } else if (table instanceof Table) {
17658                                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
17659                                                                                        if (getColumnName(columnName).equals(DlineageUtil
17660                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17661                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17662                                                                                                relation.setEffectType(EffectType.select);
17663                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17664                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17665                                                                                                pivotedColumns.add(tableColumn);
17666                                                                                                break;
17667                                                                                        }
17668                                                                                }
17669                                                                        }
17670                                                                }
17671                                                        }
17672                                                }
17673                                        }
17674                                        tables.add(pivotTable);
17675                                        tables.add(table);
17676                                }
17677                        }
17678                }
17679
17680                TPivotClause pivotClause = pivotClauses.get(0);
17681                boolean hasAlias = pivotClause.getAliasClause() != null && pivotClause.getAliasClause().getColumns() != null
17682                                && pivotClause.getAliasClause().getColumns().size() > 0;
17683                if (hasAlias) {
17684                        Alias alias = modelFactory.createAlias(pivotClause.getAliasClause());
17685                        List<TObjectName> aliasColumns = new ArrayList<TObjectName>();
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 (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
17691                                                if (pivotedColumns.contains(tableColumn)) {
17692                                                        continue;
17693                                                }
17694                                                if (tableColumn.getColumnObject() instanceof TObjectName) {
17695                                                        aliasColumns.add((TObjectName) tableColumn.getColumnObject());
17696                                                } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
17697                                                        if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
17698                                                                aliasColumns.add(((TResultColumn) tableColumn.getColumnObject()).getFieldAttr());
17699                                                        } else {
17700                                                                TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr();
17701                                                                if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
17702                                                                        TObjectName columnName = new TObjectName();
17703                                                                        columnName.setString(expr.toString());
17704                                                                        aliasColumns.add(columnName);
17705                                                                }
17706                                                        }
17707                                                }
17708                                        }
17709                                } else if (tableItem instanceof Table) {
17710                                        for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17711                                                if (pivotedColumns.contains(tableColumn)) {
17712                                                        continue;
17713                                                }
17714                                                aliasColumns.add(index, (TObjectName) tableColumn.getColumnObject());
17715                                                index++;
17716                                        }
17717                                }
17718                        }
17719
17720                        IndexedLinkedHashMap<String, ResultColumn> aliasColumnMap = new IndexedLinkedHashMap<String, ResultColumn>();
17721                        int diffCount = pivotClause.getAliasClause().getColumns().size() -  aliasColumns.size();
17722                        for (int k = 0; k < pivotClause.getAliasClause().getColumns().size(); k++) {
17723                                if (pivotClause.getAliasClause().getColumns().size() > aliasColumns.size()) {
17724                                        if (k < diffCount) {
17725                                                continue;
17726                                        }
17727                                        ResultColumn resultColumn = modelFactory.createResultColumn(alias,
17728                                                        pivotClause.getAliasClause().getColumns().getObjectName(k));
17729                                        if ((k - diffCount) < aliasColumns.size()) {
17730                                                aliasColumnMap.put(aliasColumns.get(k - diffCount).toString(), resultColumn);
17731                                        }
17732                                } else {
17733                                        ResultColumn resultColumn = modelFactory.createResultColumn(alias,
17734                                                        pivotClause.getAliasClause().getColumns().getObjectName(k));
17735                                        if (k < aliasColumns.size()) {
17736                                                aliasColumnMap.put(aliasColumns.get(k).toString(), resultColumn);
17737                                        }
17738                                }
17739                        }
17740
17741                        for (int k = 0; k < tables.size(); k++) {
17742                                Object tableItem = tables.get(k);
17743                                if (tableItem instanceof ResultSet) {
17744                                        int resultColumnSize = ((ResultSet) tableItem).getColumns().size();
17745                                        for (int x = 0; x < resultColumnSize; x++) {
17746                                                ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
17747                                                if (pivotedColumns.contains(tableColumn)) {
17748                                                        continue;
17749                                                }
17750                                                if (tableColumn.getColumnObject() instanceof TObjectName) {
17751                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17752                                                        relation.setEffectType(EffectType.select);
17753                                                        relation.setTarget(new ResultColumnRelationshipElement(
17754                                                                        aliasColumnMap.get(tableColumn.getColumnObject().toString())));
17755                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17756                                                } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
17757                                                        if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
17758                                                                ResultColumn targetColumn = aliasColumnMap.get(
17759                                                                                ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr().toString());
17760                                                                if(targetColumn == null) {
17761                                                                        continue;
17762                                                                }
17763                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17764                                                                relation.setEffectType(EffectType.select);
17765                                                                relation.setTarget(new ResultColumnRelationshipElement(targetColumn));
17766                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17767                                                        } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) {
17768                                                                TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr();
17769                                                                if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
17770                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17771                                                                        relation.setEffectType(EffectType.select);
17772                                                                        ResultColumn targetColumn = (ResultColumn) aliasColumnMap
17773                                                                                        .getValueAtIndex(aliasColumnMap.size() - resultColumnSize + x);
17774                                                                        relation.setTarget(new ResultColumnRelationshipElement(targetColumn));
17775                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17776                                                                }
17777                                                        }
17778                                                }
17779                                        }
17780                                } else if (tableItem instanceof Table) {
17781                                        for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17782                                                if (pivotedColumns.contains(tableColumn)) {
17783                                                        continue;
17784                                                }
17785                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17786                                                relation.setEffectType(EffectType.select);
17787                                                relation.setTarget(new ResultColumnRelationshipElement(
17788                                                                aliasColumnMap.get(tableColumn.getColumnObject().toString())));
17789                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17790                                        }
17791                                }
17792                        }
17793
17794                        ResultSet resultSet = modelFactory.createResultSet(stmt,
17795                                        isTopResultSet(stmt) && isShowTopSelectResultSet());
17796                        TResultColumnList columnList = stmt.getResultColumnList();
17797                        for (int i = 0; i < columnList.size(); i++) {
17798                                TResultColumn column = columnList.getResultColumn(i);
17799                                ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
17800                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
17801                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17802                                        if (columnObject.getFieldAttr() != null) {
17803                                                if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
17804                                                        resultColumn.setShowStar(false);
17805                                                        for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
17806                                                                resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject());
17807                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17808                                                                relation.setEffectType(EffectType.select);
17809                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17810                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17811                                                        }
17812                                                } else {
17813                                                        for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
17814                                                                if (getColumnName(columnObject.getFieldAttr())
17815                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17816                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17817                                                                        relation.setEffectType(EffectType.select);
17818                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17819                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17820                                                                        break;
17821                                                                }
17822                                                        }
17823                                                }
17824                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
17825                                                        .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
17826                                                for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
17827                                                        if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand())
17828                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17829                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17830                                                                relation.setEffectType(EffectType.select);
17831                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17832                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17833                                                                break;
17834                                                        }
17835                                                }
17836                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
17837                                                        .getExpressionType() == EExpressionType.function_t) {
17838                                                Function function = (Function) createFunction(columnObject.getExpr().getFunctionCall());
17839                                                for (ResultColumn arg : function.getColumns()) {
17840                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17841                                                        relation.setEffectType(EffectType.select);
17842                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17843                                                        relation.addSource(new ResultColumnRelationshipElement(arg));
17844                                                }
17845                                        }
17846                                }
17847                        }
17848                } else {
17849                        ResultSet resultSet = modelFactory.createResultSet(stmt, isTopResultSet(stmt));
17850                        TResultColumnList columnList = stmt.getResultColumnList();
17851                        for (int i = 0; i < columnList.size(); i++) {
17852                                TResultColumn column = columnList.getResultColumn(i);
17853                                ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
17854                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
17855                                        boolean fromFunction = false;
17856                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17857                                        TObjectName resultColumnFieldAttr = columnObject.getFieldAttr();
17858                                        List<TObjectName> resultColumnNames = new ArrayList<TObjectName>();
17859                                        if (resultColumnFieldAttr != null) {
17860                                                resultColumnNames.add(resultColumnFieldAttr);
17861                                        } else if (columnObject.getExpr() != null
17862                                                        && column.getExpr().getExpressionType() == EExpressionType.function_t) {
17863                                                extractFunctionObjectNames(column.getExpr().getFunctionCall(), resultColumnNames);
17864                                                fromFunction = true;
17865                                        }
17866                                        
17867                                        if (!resultColumnNames.isEmpty()) {
17868                                                for (TObjectName resultColumnName : resultColumnNames) {
17869                                                        if ("*".equals(getColumnName(resultColumnName))) {
17870                                                                resultColumn.setShowStar(false);
17871                                                                int index = 0;
17872                                                                for (int k = 0; k < tables.size(); k++) {
17873                                                                        Object tableItem = tables.get(k);
17874                                                                        if (tableItem instanceof ResultSet && !(tableItem instanceof QueryTable)) {
17875                                                                                for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) {
17876                                                                                        ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
17877                                                                                        if (pivotedColumns.contains(tableColumn)) {
17878                                                                                                continue;
17879                                                                                        }
17880                                                                                        if (tableColumn.getColumnObject() instanceof TObjectName) {
17881                                                                                                resultColumn.bindStarLinkColumn(
17882                                                                                                                (TObjectName) tableColumn.getColumnObject());
17883                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17884                                                                                                relation.setEffectType(EffectType.select);
17885                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17886                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17887                                                                                        } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
17888                                                                                                if (((TResultColumn) tableColumn.getColumnObject())
17889                                                                                                                .getFieldAttr() != null) {
17890                                                                                                        if (tableColumn.hasStarLinkColumn()) {
17891                                                                                                                for (int z = 0; z < tableColumn.getStarLinkColumnList()
17892                                                                                                                                .size(); z++) {
17893                                                                                                                        ResultColumn resultColumn1 = modelFactory
17894                                                                                                                                        .createResultColumn((ResultSet) tableItem,
17895                                                                                                                                                        tableColumn.getStarLinkColumnList().get(z));
17896                                                                                                                        DataFlowRelationship relation = modelFactory
17897                                                                                                                                        .createDataFlowRelation();
17898                                                                                                                        relation.setEffectType(EffectType.select);
17899                                                                                                                        relation.setTarget(
17900                                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
17901                                                                                                                        relation.addSource(
17902                                                                                                                                        new ResultColumnRelationshipElement(resultColumn1));
17903                                                                                                                        tableColumn.getStarLinkColumns().remove(getColumnName(
17904                                                                                                                                        tableColumn.getStarLinkColumnList().get(z)));
17905                                                                                                                        z--;
17906                                                                                                                }
17907                                                                                                        } else {
17908                                                                                                                resultColumn.bindStarLinkColumn(
17909                                                                                                                                ((TResultColumn) tableColumn.getColumnObject())
17910                                                                                                                                                .getFieldAttr());
17911                                                                                                                DataFlowRelationship relation = modelFactory
17912                                                                                                                                .createDataFlowRelation();
17913                                                                                                                relation.setEffectType(EffectType.select);
17914                                                                                                                relation.setTarget(
17915                                                                                                                                new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject())
17916                                                                                                                                                .getFieldAttr()));
17917                                                                                                                relation.addSource(
17918                                                                                                                                new ResultColumnRelationshipElement(tableColumn));
17919                                                                                                        }
17920                                                                                                } else if (((TResultColumn) tableColumn.getColumnObject())
17921                                                                                                                .getExpr() != null) {
17922                                                                                                        TExpression expr = ((TResultColumn) tableColumn.getColumnObject())
17923                                                                                                                        .getExpr();
17924                                                                                                        if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
17925                                                                                                                TObjectName columnName = new TObjectName();
17926                                                                                                                columnName.setString(expr.toString());
17927                                                                                                                resultColumn.bindStarLinkColumn(columnName);
17928                                                                                                                DataFlowRelationship relation = modelFactory
17929                                                                                                                                .createDataFlowRelation();
17930                                                                                                                relation.setEffectType(EffectType.select);
17931                                                                                                                relation.setTarget(
17932                                                                                                                                new ResultColumnRelationshipElement(resultColumn, columnName));
17933                                                                                                                relation.addSource(
17934                                                                                                                                new ResultColumnRelationshipElement(tableColumn));
17935                                                                                                        }
17936                                                                                                }
17937                                                                                        }
17938                                                                                }
17939                                                                        } else if (tableItem instanceof Table) {
17940                                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17941                                                                                        if (pivotedColumns.contains(tableColumn)) {
17942                                                                                                continue;
17943                                                                                        }
17944                                                                                        resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(),
17945                                                                                                        index);
17946                                                                                        index++;
17947                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17948                                                                                        relation.setEffectType(EffectType.select);
17949                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17950                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17951                                                                                }
17952                                                                        } else if (tableItem instanceof QueryTable) {
17953                                                                                for (ResultColumn tableColumn : ((QueryTable) tableItem).getColumns()) {
17954                                                                                        if (pivotedColumns.contains(tableColumn)) {
17955                                                                                                continue;
17956                                                                                        }
17957                                                                                        TObjectName column1 = new TObjectName();
17958                                                                                        column1.setString(tableColumn.getName());
17959                                                                                        resultColumn.bindStarLinkColumn(column1, index);
17960                                                                                        index++;
17961                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17962                                                                                        relation.setEffectType(EffectType.select);
17963                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, column1));
17964                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn), false);
17965                                                                                }
17966                                                                        }
17967                                                                }
17968                                                        } else {
17969                                                                ResultColumn pivotedTableColumn = getPivotedTableColumn(pivotedTable, resultColumnName);
17970                                                                        if (pivotedTableColumn != null) {
17971                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17972                                                                                relation.setEffectType(EffectType.select);
17973                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17974                                                                                relation.addSource(new ResultColumnRelationshipElement(pivotedTableColumn));
17975                                                                        } else {
17976                                                                                for (int k = 0; k < tables.size(); k++) {
17977                                                                                        Object tableItem = tables.get(k);
17978                                                                                        if (tableItem instanceof ResultSet) {
17979                                                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
17980                                                                                                        if (DlineageUtil
17981                                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()).equals(getColumnName(resultColumnName))) {
17982                                                                                                                if (fromFunction) {
17983                                                                                                                        Function function = (Function)createPivotedFunction(column.getExpr().getFunctionCall(), tableColumn);
17984                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17985                                                                                                                        relation.setEffectType(EffectType.select);
17986                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17987                                                                                                                        if (function.getColumns() != null && !function.getColumns().isEmpty()) {
17988                                                                                                                                for (ResultColumn functionColumn : function.getColumns()) {
17989                                                                                                                                        relation.addSource(new ResultColumnRelationshipElement(functionColumn));
17990                                                                                                                                }
17991                                                                                                                        }
17992                                                                                                                } else {
17993                                                                                                                        DataFlowRelationship relation = modelFactory
17994                                                                                                                                        .createDataFlowRelation();
17995                                                                                                                        relation.setEffectType(EffectType.select);
17996                                                                                                                        relation.setTarget(
17997                                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
17998                                                                                                                        relation.addSource(
17999                                                                                                                                        new ResultColumnRelationshipElement(tableColumn));
18000                                                                                                                }
18001                                                                                                                break;
18002                                                                                                        }
18003                                                                                                }
18004                                                                                        } else if (tableItem instanceof Table) {
18005                                                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
18006                                                                                                        if (getColumnName(resultColumnName).equals(DlineageUtil
18007                                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
18008                                                                                                                DataFlowRelationship relation = modelFactory
18009                                                                                                                                .createDataFlowRelation();
18010                                                                                                                relation.setEffectType(EffectType.select);
18011                                                                                                                relation.setTarget(
18012                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
18013                                                                                                                relation.addSource(
18014                                                                                                                                new TableColumnRelationshipElement(tableColumn));
18015                                                                                                                break;
18016                                                                                                        }
18017                                                                                                }
18018                                                                                        }
18019                                                                                }
18020                                                                        }
18021                                                                }
18022                                                }
18023                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
18024                                                        .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
18025                                                for (int k = 0; k < tables.size(); k++) {
18026                                                        Object tableItem = tables.get(k);
18027                                                        if (tableItem instanceof ResultSet) {
18028                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
18029                                                                        if (columnObject.getExpr().getRightOperand().getObjectOperand() != null
18030                                                                                        && getColumnName(
18031                                                                                                        columnObject.getExpr().getRightOperand().getObjectOperand())
18032                                                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(
18033                                                                                                                                        tableColumn.getName()))) {
18034                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18035                                                                                relation.setEffectType(EffectType.select);
18036                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18037                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18038                                                                                break;
18039                                                                        } else if (columnObject.getExpr().getRightOperand()
18040                                                                                        .getExpressionType() == EExpressionType.function_t) {
18041                                                                                List<TExpression> expressions = new ArrayList<TExpression>();
18042                                                                                getFunctionExpressions(expressions, new ArrayList<TExpression>(),
18043                                                                                                columnObject.getExpr().getRightOperand().getFunctionCall());
18044                                                                                for (int j = 0; j < expressions.size(); j++) {
18045                                                                                        columnsInExpr visitor = new columnsInExpr();
18046                                                                                        expressions.get(j).inOrderTraverse(visitor);
18047                                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
18048                                                                                        if (objectNames == null) {
18049                                                                                                continue;
18050                                                                                        }
18051                                                                                        for (TObjectName columnName : objectNames) {
18052                                                                                                if (getColumnName(columnName).equals(DlineageUtil
18053                                                                                                                .getIdentifierNormalColumnName(tableColumn.getName()))) {
18054                                                                                                        DataFlowRelationship relation = modelFactory
18055                                                                                                                        .createDataFlowRelation();
18056                                                                                                        relation.setEffectType(EffectType.select);
18057                                                                                                        relation.setTarget(
18058                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
18059                                                                                                        relation.addSource(
18060                                                                                                                        new ResultColumnRelationshipElement(tableColumn));
18061                                                                                                        break;
18062                                                                                                }
18063                                                                                        }
18064                                                                                }
18065                                                                        }
18066                                                                }
18067                                                        } else if (tableItem instanceof Table) {
18068                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
18069                                                                        if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand())
18070                                                                                        .equals(DlineageUtil
18071                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
18072                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18073                                                                                relation.setEffectType(EffectType.select);
18074                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18075                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18076                                                                                break;
18077                                                                        }
18078                                                                }
18079                                                        }
18080                                                }
18081                                        }
18082                                }
18083                        }
18084                }
18085
18086                analyzeSelectIntoClause(stmt);
18087        }
18088
18089        private Function createPivotedFunction(TFunctionCall functionCall, ResultColumn sourceColumn) {
18090                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
18091                ResultColumn column = modelFactory.createFunctionResultColumn(function,
18092                                ((TFunctionCall) functionCall).getFunctionName());
18093                if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) {
18094                        // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP
18095                        // COUNT特殊处理,不和参数关联
18096                        if (option.isShowCountTableColumn()) {
18097                                analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn);
18098                        }
18099                } else {
18100                        analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn);
18101                        Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function));
18102                        if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) {
18103                                ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next();
18104                                if (functionTableModel.getColumns() != null) {
18105                                        for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
18106                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18107                                                        relation.setEffectType(EffectType.select);
18108                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18109                                                        relation.addSource(new ResultColumnRelationshipElement(
18110                                                                        functionTableModel.getColumns().get(j)));
18111                                        }
18112                                }
18113                        }
18114                }
18115                return function;
18116        }
18117
18118        private void analyzePivotedFunctionArgumentsDataFlowRelation(ResultColumn column, TFunctionCall functionCall,
18119                        ResultColumn sourceColumn) {
18120                List<TExpression> directExpressions = new ArrayList<TExpression>();
18121                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18122
18123                getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
18124
18125                for (int j = 0; j < directExpressions.size(); j++) {
18126                        columnsInExpr visitor = new columnsInExpr();
18127                        directExpressions.get(j).inOrderTraverse(visitor);
18128
18129                        List<TObjectName> objectNames = visitor.getObjectNames();
18130                        List<TParseTreeNode> constants = visitor.getConstants();
18131
18132                        if (objectNames != null) {
18133                                for (TObjectName name : objectNames) {
18134                                        if (DlineageUtil.compareColumnIdentifier(name.toString(), sourceColumn.getName())) {
18135                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18136                                                relation.setEffectType(EffectType.select);
18137                                                relation.setTarget(new ResultColumnRelationshipElement(column));
18138                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
18139                                        }
18140                                }
18141                        }
18142                        if (constants != null) {
18143                                for (TParseTreeNode name : constants) {
18144                                        if (name.toString().equals(sourceColumn.getName())) {
18145                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18146                                                relation.setEffectType(EffectType.select);
18147                                                relation.setTarget(new ResultColumnRelationshipElement(column));
18148                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
18149                                        }
18150                                }
18151                        }
18152                }
18153        }
18154        
18155        private void extractFunctionObjectNames(TFunctionCall functionCall, List<TObjectName> resultColumnNames) {
18156                List<TExpression> directExpressions = new ArrayList<TExpression>();
18157                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18158
18159                getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
18160
18161                for (int j = 0; j < directExpressions.size(); j++) {
18162                        columnsInExpr visitor = new columnsInExpr();
18163                        directExpressions.get(j).inOrderTraverse(visitor);
18164
18165                        List<TObjectName> objectNames = visitor.getObjectNames();
18166                        List<TParseTreeNode> functions = visitor.getFunctions();
18167                        List<TParseTreeNode> constants = visitor.getConstants(); 
18168
18169                        if (objectNames != null) {
18170                                resultColumnNames.addAll(objectNames);
18171                        }
18172                        
18173                        if (constants != null) {
18174                                for(TParseTreeNode item: constants) {
18175                                        if(item instanceof TConstant && ((TConstant) item).getLiteralType().getText().equals(ELiteralType.string_et.getText())) {
18176                                                TObjectName object = new TObjectName();
18177                                                object.setString(item.toString());
18178                                                resultColumnNames.add(object);
18179                                        }
18180                                }
18181                        }
18182
18183                        if (functions != null && !functions.isEmpty()) {
18184                                for (TParseTreeNode function : functions) {
18185                                        if (function instanceof TFunctionCall) {
18186                                                extractFunctionObjectNames((TFunctionCall) function, resultColumnNames);
18187                                        }
18188                                }
18189                        }
18190                }
18191        }
18192
18193        private String getResultColumnString(TResultColumn resultColumn) {
18194                if (resultColumn.getAliasClause() != null) {
18195                        return resultColumn.getAliasClause().toString();
18196                }
18197                return resultColumn.toString();
18198        }
18199
18200        private void analyzeBigQueryUnnest(TSelectSqlStatement stmt, TTable table) {
18201                Table unnestTable = modelFactory.createTableFromCreateDDL(table, false, getTempTableName(table));
18202                unnestTable.setSubType(SubType.unnest);
18203                TUnnestClause clause = table.getUnnestClause();
18204                TExpression arrayExpr = clause.getArrayExpr();
18205                if (arrayExpr == null){
18206                        if (clause.getColumns() != null) {
18207                                for (TObjectName column : clause.getColumns()) {
18208                                        if (clause.getDerivedColumnList() != null) {
18209                                                unnestTable.setCreateTable(true);
18210                                                for (int i = 0; i < clause.getDerivedColumnList().size(); i++) {
18211                                                        TObjectName columnName = new TObjectName();
18212                                                        columnName.setString(column.getColumnNameOnly() + "."
18213                                                                        + clause.getDerivedColumnList().getObjectName(i).getColumnNameOnly());
18214                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true);
18215                                                        List<TObjectName> columns = new ArrayList<TObjectName>();
18216                                                        columns.add(column);
18217                                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18218                                                }
18219                                        }
18220                                        else {
18221                                                unnestTable.setCreateTable(true);
18222                                                boolean find = false;
18223                                                if (column.getSourceTable() != null && modelManager.getModel(column.getSourceTable()) instanceof Table) {
18224                                                        Table sourceTable = (Table)modelManager.getModel(column.getSourceTable());
18225                                                        if(sourceTable!=null) {
18226                                                                for(TableColumn tableColumn: sourceTable.getColumns()) {
18227                                                                        if(tableColumn.isStruct()) {
18228                                                                                List<String> names = SQLUtil.parseNames(tableColumn.getName());
18229                                                                                if (names.get(0).equalsIgnoreCase(column.getColumnNameOnly())) {
18230                                                                                        TObjectName columnName = new TObjectName();
18231                                                                                        columnName.setString(tableColumn.getName());
18232                                                                                        TableColumn unnestTableColumn = modelFactory.createTableColumn(unnestTable,
18233                                                                                                        columnName, true);
18234                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18235                                                                                        relation.setEffectType(EffectType.select);
18236                                                                                        relation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
18237                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18238                                                                                        find = true;
18239                                                                                }
18240                                                                        }
18241                                                                }
18242                                                        }
18243                                                }
18244                                                if (!find) {
18245                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, column, true);
18246                                                        List<TObjectName> columns = new ArrayList<TObjectName>();
18247                                                        columns.add(column);
18248                                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18249                                                }
18250                                        }
18251                                }
18252                        }
18253                        return;
18254                }
18255                List<TExpression> expressions = new ArrayList<TExpression>();
18256                TExpressionList values = arrayExpr.getExprList();
18257                if (values == null) {
18258                        expressions.add(arrayExpr);
18259                }
18260                else {
18261                        for(TExpression value: values) {
18262                                expressions.add(value);
18263                        }
18264                }
18265                for (TExpression value : expressions) {
18266                        unnestTable.setCreateTable(true);
18267                        if (value.getExpressionType() == EExpressionType.simple_object_name_t) {
18268                                if (table.getAliasClause() != null) {
18269                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18270                                                        table.getAliasClause().getAliasName(), true);
18271                                        columnsInExpr visitor = new columnsInExpr();
18272                                        value.inOrderTraverse(visitor);
18273                                        List<TObjectName> columns = visitor.getObjectNames();
18274                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18275                                } else {
18276                                        TResultColumnList resultColumnList = stmt.getResultColumnList();
18277                                        for (int i = 0; i < resultColumnList.size(); i++) {
18278                                                TObjectName firstColumn = new TObjectName();
18279                                                firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly());
18280                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18281                                                columnsInExpr visitor = new columnsInExpr();
18282                                                value.inOrderTraverse(visitor);
18283                                                List<TObjectName> columns = visitor.getObjectNames();
18284                                                analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18285                                        }
18286                                }
18287                        } else if (value.getExpressionType() == EExpressionType.function_t) {
18288                                if (table.getAliasClause() != null) {
18289                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18290                                                        table.getAliasClause().getAliasName(), true);
18291                                        columnsInExpr visitor = new columnsInExpr();
18292                                        value.inOrderTraverse(visitor);
18293                                        List<TParseTreeNode> functions = visitor.getFunctions();
18294                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.select, null);
18295                                } else {
18296                                        TResultColumnList resultColumnList = stmt.getResultColumnList();
18297                                        for (int i = 0; i < resultColumnList.size(); i++) {
18298                                                TObjectName firstColumn = new TObjectName();
18299                                                firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly());
18300                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18301                                                columnsInExpr visitor = new columnsInExpr();
18302                                                value.inOrderTraverse(visitor);
18303                                                List<TObjectName> columns = visitor.getObjectNames();
18304                                                analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18305                                        }
18306                                }
18307                        } else if (value.getExpressionType() == EExpressionType.simple_constant_t) {
18308                                if (table.getAliasClause() != null) {
18309                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18310                                                        table.getAliasClause().getAliasName(), true);
18311                                        columnsInExpr visitor = new columnsInExpr();
18312                                        value.inOrderTraverse(visitor);
18313                                        List<TParseTreeNode> constants = visitor.getConstants();
18314                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18315                                } else {
18316                                        TObjectName firstColumn = new TObjectName();
18317                                        firstColumn.setString("f0_");
18318                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18319                                        columnsInExpr visitor = new columnsInExpr();
18320                                        value.inOrderTraverse(visitor);
18321                                        List<TParseTreeNode> constants = visitor.getConstants();
18322                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18323                                }
18324                        } else if (value.getExpressionType() == EExpressionType.list_t) {
18325                                if (arrayExpr.getTypeName() != null && arrayExpr.getTypeName().getColumnDefList() != null) {
18326                                        for (int i = 0; i < arrayExpr.getTypeName().getColumnDefList().size(); i++) {
18327                                                TColumnDefinition column = arrayExpr.getTypeName().getColumnDefList().getColumn(i);
18328                                                if (column != null && column.getColumnName() != null) {
18329                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18330                                                                        column.getColumnName(), true);
18331                                                        columnsInExpr visitor = new columnsInExpr();
18332                                                        value.getExprList().getExpression(i).inOrderTraverse(visitor);
18333                                                        List<TParseTreeNode> constants = visitor.getConstants();
18334                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18335                                                }
18336                                        }
18337                                } else {
18338                                        for (int i = 0; i < value.getExprList().size(); i++) {
18339                                                TObjectName firstColumn = new TObjectName();
18340                                                firstColumn.setString("f" + i + "_");
18341                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18342                                                columnsInExpr visitor = new columnsInExpr();
18343                                                value.getExprList().getExpression(i).inOrderTraverse(visitor);
18344                                                List<TParseTreeNode> constants = visitor.getConstants();
18345                                                analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18346                                        }
18347                                }
18348                        } else if (value.getExpressionType() == EExpressionType.subquery_t) {
18349                                analyzeSelectStmt(value.getSubQuery());
18350                                ResultSet resultSet = (ResultSet) modelManager.getModel(value.getSubQuery());
18351                                if (resultSet != null) {
18352                                        for (int i = 0; i < resultSet.getColumns().size(); i++) {
18353                                                TObjectName columnName =  new TObjectName();
18354                                                if(resultSet.getColumns().get(i).getAlias()!=null) {
18355                                                        columnName.setString(resultSet.getColumns().get(i).getAlias());
18356                                                }
18357                                                else {
18358                                                        columnName.setString(getColumnName(resultSet.getColumns().get(i).getName()));
18359                                                }
18360                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true);
18361                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18362                                                relation.setEffectType(EffectType.select);
18363                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
18364                                                relation.addSource(
18365                                                                new ResultColumnRelationshipElement(resultSet.getColumns().get(i)));
18366                                        }
18367                                }
18368                        }
18369                }
18370        }
18371
18372        private void analyzePrestoUnnest(TSelectSqlStatement stmt, TTable table) {
18373                List<Table> tables = new ArrayList<Table>();
18374                TTable targetTable = stmt.getTables().getTable(0);
18375                Table stmtTable = modelFactory.createTable(targetTable);
18376                Object sourceTable = null;
18377                if (targetTable.getSubquery() != null) {
18378                        analyzeSelectStmt(targetTable.getSubquery());
18379                        if (targetTable.getSubquery().isCombinedQuery()) {
18380                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(targetTable.getSubquery());
18381                                sourceTable = sourceResultSet;
18382                        } else if (targetTable.getSubquery().getResultColumnList() != null) {
18383                                ResultSet sourceResultSet = (ResultSet) modelManager
18384                                                .getModel(targetTable.getSubquery().getResultColumnList());
18385                                sourceTable = sourceResultSet;
18386                        } else if (targetTable.getSubquery().getValueClause() != null) {
18387                                List<TResultColumnList> rowList = targetTable.getSubquery().getValueClause().getRows();
18388                                if (rowList != null && rowList.size() > 0) {
18389                                        Table valuesTable = modelFactory.createTableByName("Values-Table", true);
18390                                        int columnCount = rowList.get(0).size();
18391                                        for (int j = 1; j <= columnCount; j++) {
18392                                                TObjectName columnName = new TObjectName();
18393                                                TResultColumn columnObject = rowList.get(0).getResultColumn(j - 1);
18394                                                if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) {
18395                                                        columnName.setString(columnObject.getExpr().getLeftOperand().toString());
18396                                                } else {
18397                                                        columnName.setString(columnObject.getExpr().toString());
18398                                                }
18399                                                modelFactory.createTableColumn(valuesTable, columnName, true);
18400                                        }
18401                                        valuesTable.setCreateTable(true);
18402                                        valuesTable.setSubType(SubType.values_table);
18403                                        sourceTable = valuesTable;
18404                                }
18405                        }
18406                }
18407                tables.add(stmtTable);
18408                Table unnestTable = modelFactory.createTable(table);
18409                unnestTable.setSubType(SubType.unnest);
18410                tables.add(unnestTable);
18411                if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null
18412                                && table.getUnnestClause().getColumns() != null) {
18413                        int unnestTableSize = table.getUnnestClause().getColumns().size();
18414                        for (int i = 0; i < table.getAliasClause().getColumns().size(); i++) {
18415                                TableColumn sourceColumn = null;
18416                                if (unnestTableSize > i) {
18417                                        sourceColumn = modelFactory.createTableColumn(stmtTable,
18418                                                        table.getUnnestClause().getColumns().getObjectName(i), true);
18419                                        if (sourceTable instanceof Table) {
18420                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18421                                                relation.setEffectType(EffectType.select);
18422                                                relation.setTarget(new TableColumnRelationshipElement(sourceColumn));
18423                                                relation.addSource(
18424                                                                new TableColumnRelationshipElement(((Table) sourceTable).getColumns().get(i)));
18425                                        } else if (sourceTable instanceof ResultSet) {
18426                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18427                                                relation.setEffectType(EffectType.select);
18428                                                relation.setTarget(new TableColumnRelationshipElement(sourceColumn));
18429                                                relation.addSource(
18430                                                                new ResultColumnRelationshipElement(((ResultSet) sourceTable).getColumns().get(i)));
18431                                        }
18432                                } else {
18433                                        sourceColumn = modelFactory.createTableColumn(stmtTable,
18434                                                        table.getUnnestClause().getColumns().getObjectName(unnestTableSize - 1), true);
18435                                }
18436                                TableColumn targetColumn = modelFactory.createTableColumn(unnestTable,
18437                                                table.getAliasClause().getColumns().getObjectName(i), true);
18438                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18439                                relation.setEffectType(EffectType.select);
18440                                relation.setTarget(new TableColumnRelationshipElement(targetColumn));
18441                                relation.addSource(new TableColumnRelationshipElement(sourceColumn));
18442                        }
18443                }
18444
18445                ResultSet resultSet = modelFactory.createResultSet(stmt,
18446                                isTopResultSet(stmt) && isShowTopSelectResultSet());
18447                TResultColumnList columnList = stmt.getResultColumnList();
18448                for (int i = 0; i < columnList.size(); i++) {
18449                        TResultColumn column = columnList.getResultColumn(i);
18450                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
18451                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
18452                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
18453                                if (columnObject.getFieldAttr() != null) {
18454                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
18455                                                for (int k = 0; k < tables.size(); k++) {
18456                                                        Table tableItem = tables.get(k);
18457                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
18458                                                                resultColumn.bindStarLinkColumn(tableColumn.getColumnObject());
18459                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18460                                                                relation.setEffectType(EffectType.select);
18461                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject()));
18462                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18463                                                        }
18464                                                }
18465                                        } else {
18466                                                boolean match = false;
18467                                                for (int k = 0; k < tables.size(); k++) {
18468                                                        Table tableItem = tables.get(k);
18469                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
18470                                                                if (getColumnName(columnObject.getFieldAttr())
18471                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18472                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18473                                                                        relation.setEffectType(EffectType.select);
18474                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18475                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18476                                                                        match = true;
18477                                                                }
18478                                                        }
18479                                                }
18480                                                if (!match) {
18481                                                        TableColumn tableColumn = modelFactory.createTableColumn(stmtTable,
18482                                                                        columnObject.getFieldAttr(), false);
18483                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18484                                                        relation.setEffectType(EffectType.select);
18485                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18486                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18487                                                }
18488                                        }
18489                                }
18490                        }
18491                }
18492        }
18493
18494        private void analyzeLateralView(TSelectSqlStatement stmt, TTable table, ArrayList<TLateralView> lateralViews) {
18495                List<Object> tables = new ArrayList<Object>();
18496                Object stmtTable = null;
18497                if(table.getSubquery()!=null) {
18498                        stmtTable = modelFactory.createQueryTable(table);
18499                        tables.add(stmtTable);
18500                }
18501                else {
18502                        stmtTable = modelFactory.createTable(table);
18503                        tables.add(stmtTable);
18504                }
18505                for (int i = 0; i < lateralViews.size(); i++) {
18506                        TLateralView lateralView = lateralViews.get(i);
18507                        TFunctionCall functionCall = lateralView.getUdtf();
18508                        List<TExpression> expressions = new ArrayList<TExpression>();
18509                        if (functionCall == null) {
18510                                continue;
18511                        }
18512                        Function function = modelFactory.createFunction(functionCall);
18513                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
18514                                        ((TFunctionCall) functionCall).getFunctionName());
18515
18516                        Table lateralTable = null;
18517                        if (lateralView.getTableAlias() != null) {
18518                                lateralTable = modelFactory.createTableByName(lateralView.getTableAlias().getAliasName(), true);
18519                        } else {
18520                                lateralTable = modelFactory.createTableByName(functionCall.toString(), true);
18521                        }
18522
18523                        for (int j = 0; j < lateralView.getColumnAliasList().size(); j++) {
18524                                TObjectName viewColumn = lateralView.getColumnAliasList().getObjectName(j);
18525                                TableColumn tableColumn = modelFactory.createTableColumn(lateralTable, viewColumn, true);
18526
18527                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18528                                relation.setEffectType(EffectType.select);
18529                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
18530                                relation.addSource(new ResultColumnRelationshipElement(column));
18531                        }
18532
18533                        getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall);
18534                        for (int j = 0; j < expressions.size(); j++) {
18535                                columnsInExpr visitor = new columnsInExpr();
18536                                expressions.get(j).inOrderTraverse(visitor);
18537                                List<TObjectName> objectNames = visitor.getObjectNames();
18538                                if (objectNames == null) {
18539                                        continue;
18540                                }
18541                                for (TObjectName columnName : objectNames) {
18542                                        boolean match = false;
18543                                        for (int k = 0; k < tables.size(); k++) {
18544                                                Object item = tables.get(k);
18545                                                if(item instanceof Table) {
18546                                                        Table tableItem = (Table)item;
18547                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
18548                                                                if (getColumnName(columnName)
18549                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18550                                                                        match = true;
18551                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18552                                                                        relation.setEffectType(EffectType.select);
18553                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18554                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18555                                                                }
18556                                                        }
18557                                                }
18558                                                else {
18559                                                        ResultSet tableItem = (ResultSet)item;
18560                                                        for (ResultColumn tableColumn : tableItem.getColumns()) {
18561                                                                if (getColumnName(columnName)
18562                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18563                                                                        match = true;
18564                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18565                                                                        relation.setEffectType(EffectType.select);
18566                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18567                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18568                                                                }
18569                                                        }
18570                                                }
18571                                        }
18572                                        if (!match) {
18573                                                if(stmtTable instanceof Table) {
18574                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable, columnName, false);
18575                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18576                                                        relation.setEffectType(EffectType.select);
18577                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18578                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18579                                                }
18580                                                else {
18581                                                        ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable, columnName, false);
18582                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18583                                                        relation.setEffectType(EffectType.select);
18584                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18585                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18586                                                }
18587                                        }
18588                                }
18589                                List<TParseTreeNode> constants = visitor.getConstants();
18590                                if (!constants.isEmpty()) {
18591                                        if (option.isShowConstantTable()) {
18592                                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
18593                                                for (TParseTreeNode constant : constants) {
18594                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18595                                                        relation.setEffectType(EffectType.select);
18596                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18597                                                        if (constant instanceof TConstant) {
18598                                                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
18599                                                                                (TConstant) constant);
18600                                                                relation.addSource(new ConstantRelationshipElement(constantColumn));
18601                                                        } else if (constant instanceof TObjectName) {
18602                                                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
18603                                                                                (TObjectName) constant, false);
18604                                                                relation.addSource(new ConstantRelationshipElement(constantColumn));
18605                                                        }
18606                                                }
18607                                        }
18608                                }
18609                                
18610                                List<TParseTreeNode> functions = visitor.getFunctions();
18611                                if (functions != null && !functions.isEmpty()) {
18612                                        analyzeFunctionDataFlowRelation(column, functions, EffectType.function);
18613                                }
18614                        }
18615                        tables.add(lateralTable);
18616                }
18617
18618                ResultSet resultSet = modelFactory.createResultSet(stmt,
18619                                isTopResultSet(stmt) && isShowTopSelectResultSet());
18620                TResultColumnList columnList = stmt.getResultColumnList();
18621                for (int i = 0; i < columnList.size(); i++) {
18622                        TResultColumn column = columnList.getResultColumn(i);
18623                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
18624                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
18625                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
18626                                if (columnObject.getFieldAttr() != null) {
18627                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
18628                                                for (int k = 0; k < tables.size(); k++) {
18629                                                        Object item = tables.get(k);
18630                                                        if(item instanceof Table) {
18631                                                                Table tableItem = (Table)item;
18632                                                                for (TableColumn tableColumn : tableItem.getColumns()) {
18633                                                                        resultColumn.bindStarLinkColumn(tableColumn.getColumnObject());
18634                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18635                                                                        relation.setEffectType(EffectType.select);
18636                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject()));
18637                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18638                                                                }
18639                                                        }
18640                                                        else {
18641                                                                ResultSet tableItem = (ResultSet)item;
18642                                                                for (ResultColumn tableColumn : tableItem.getColumns()) {
18643                                                                        TObjectName linkColumn = new TObjectName();
18644                                                                        linkColumn.setString(tableColumn.getName());
18645                                                                        resultColumn.bindStarLinkColumn(linkColumn);
18646                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18647                                                                        relation.setEffectType(EffectType.select);
18648                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, linkColumn));
18649                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18650                                                                }
18651                                                        }
18652                                                }
18653                                        } else {
18654                                                boolean match = false;
18655                                                for (int k = 0; k < tables.size(); k++) {
18656                                                        Object item = tables.get(k);
18657                                                        if(item instanceof Table) {
18658                                                                Table tableItem = (Table)item;
18659                                                                for (TableColumn tableColumn : tableItem.getColumns()) {
18660                                                                        if (getColumnName(columnObject.getFieldAttr())
18661                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18662                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18663                                                                                relation.setEffectType(EffectType.select);
18664                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18665                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18666                                                                                match = true;
18667                                                                        }
18668                                                                }
18669                                                        }
18670                                                        else {
18671                                                                ResultSet tableItem = (ResultSet)item;
18672                                                                for (ResultColumn tableColumn : tableItem.getColumns()) {
18673                                                                        if (getColumnName(columnObject.getFieldAttr())
18674                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18675                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18676                                                                                relation.setEffectType(EffectType.select);
18677                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18678                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18679                                                                                match = true;
18680                                                                        }
18681                                                                }
18682                                                        }
18683                                                }
18684                                                if (!match) {
18685                                                        if(stmtTable instanceof Table) {
18686                                                                TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable,
18687                                                                                columnObject.getFieldAttr(), false);
18688                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18689                                                                relation.setEffectType(EffectType.select);
18690                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18691                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18692                                                        }
18693                                                        else {
18694                                                                ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable,
18695                                                                                columnObject.getFieldAttr(), false);
18696                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18697                                                                relation.setEffectType(EffectType.select);
18698                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18699                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18700                                                        }
18701                                                }
18702                                        }
18703                                }
18704                                else if (columnObject.getExpr() != null
18705                                                && columnObject.getExpr().getExpressionType() == EExpressionType.function_t) {
18706                                        analyzeResultColumn(column, EffectType.select);
18707                                        for (int k = 0; k < tables.size(); k++) {
18708                                                Object item = tables.get(k);
18709                                                if (item instanceof Table) {
18710                                                        Table tableItem = (Table) item;
18711                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
18712                                                                if (getColumnName(resultColumn.getName()).equals(
18713                                                                                DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18714                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18715                                                                        relation.setEffectType(EffectType.select);
18716                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18717                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18718                                                                }
18719                                                        }
18720                                                } else {
18721                                                        ResultSet tableItem = (ResultSet) item;
18722                                                        for (ResultColumn tableColumn : tableItem.getColumns()) {
18723                                                                if (getColumnName(resultColumn.getName()).equals(
18724                                                                                DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18725                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18726                                                                        relation.setEffectType(EffectType.select);
18727                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18728                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18729                                                                }
18730                                                        }
18731                                                }
18732                                        }
18733                                }
18734                        }
18735                }
18736        }
18737
18738        private boolean isFromFunction(TObjectName object) {
18739
18740                Stack<TParseTreeNode> nodes = object.getStartToken().getNodesStartFromThisToken();
18741                if (nodes != null) {
18742                        for (int i = 0; i < nodes.size(); i++) {
18743                                if (nodes.get(i) instanceof TFunctionCall) {
18744                                        return true;
18745                                }
18746                        }
18747                }
18748                return false;
18749        }
18750
18751        private TResultColumnList getResultColumnList(TSelectSqlStatement stmt) {
18752                if (stmt.isCombinedQuery()) {
18753                        TResultColumnList columns = getResultColumnList(stmt.getLeftStmt());
18754                        if (columns != null) {
18755                                return columns;
18756                        }
18757                        return getResultColumnList(stmt.getRightStmt());
18758                } else {
18759                        return stmt.getResultColumnList();
18760                }
18761        }
18762
18763        private void createPseudoImpactRelation(TCustomSqlStatement stmt, ResultSet resultSetModel, EffectType effectType) {
18764                if (stmt.getTables() != null) {
18765                        for (int i = 0; i < stmt.getTables().size(); i++) {
18766                                TTable table = stmt.getTables().getTable(i);
18767                                if (modelManager.getModel(table) instanceof ResultSet) {
18768                                        ResultSet tableModel = (ResultSet) modelManager.getModel(table);
18769                                        if (tableModel != resultSetModel && !tableModel.getRelationRows().getHoldRelations().isEmpty()) {
18770                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
18771                                                impactRelation.setEffectType(effectType);
18772                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18773                                                                tableModel.getRelationRows()));
18774                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18775                                                                resultSetModel.getRelationRows()));
18776                                        }
18777                                } else if (modelManager.getModel(table) instanceof Table) {
18778                                        Table tableModel = (Table) modelManager.getModel(table);
18779                                        if (!tableModel.getRelationRows().getHoldRelations().isEmpty()) {
18780                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
18781                                                impactRelation.setEffectType(effectType);
18782                                                impactRelation.addSource(
18783                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
18784                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18785                                                                resultSetModel.getRelationRows()));
18786                                        }
18787                                }
18788                        }
18789                }
18790        }
18791
18792        private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions,
18793                        EffectType effectType) {
18794                for (int i = 0; i < functions.size(); i++) {
18795                        TParseTreeNode functionCall = functions.get(i);
18796                        if (functionCall instanceof TFunctionCall) {
18797                                String functionName = DlineageUtil.getIdentifierNormalTableName(
18798                                                DlineageUtil.getFunctionNameWithArgNum((TFunctionCall) functionCall));
18799                                Procedure procedure = modelManager.getProcedureByName(functionName);
18800                                if (procedure != null) {
18801                                        String procedureParent = getProcedureParentName(stmtStack.peek());
18802                                        if (procedureParent != null) {
18803                                                Procedure caller = modelManager
18804                                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
18805                                                if (caller != null) {
18806                                                        CallRelationship callRelation = modelFactory.createCallRelation();
18807                                                        callRelation.setCallObject(functionCall);
18808                                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
18809                                                        callRelation.addSource(new ProcedureRelationshipElement(procedure));
18810                                                        if (isBuiltInFunctionName(((TFunctionCall)functionCall).getFunctionName())||isKeyword(((TFunctionCall)functionCall).getFunctionName())) {
18811                                                                callRelation.setBuiltIn(true);
18812                                                        }
18813                                                }
18814                                        }
18815                                        if (procedure.getProcedureObject() instanceof TCreateFunctionStmt) {
18816                                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt)procedure.getProcedureObject();
18817                                                TTypeName dataType = createFunction.getReturnDataType();
18818                                                if (dataType!=null && dataType.getTypeOfList() != null && dataType.getTypeOfList().getColumnDefList() != null) {
18819                                                        Object modelObject = modelManager.getModel(gspObject);
18820                                                        if(modelObject instanceof ResultColumn) {
18821                                                                ResultColumn resultColumn = (ResultColumn)modelObject;
18822                                                                ResultSet resultSet = resultColumn.getResultSet();
18823                                                                for (int j = 0; j < dataType.getTypeOfList().getColumnDefList().size(); j++) {
18824                                                                        TObjectName columnName = new TObjectName();
18825                                                                        if( dataType.getDataType() == EDataType.array_t) {
18826//                                                                              columnName.setString(resultColumn.getName() + ".array."
18827//                                                                                              + dataType.getTypeOfList().getColumnDefList().getColumn(j)
18828//                                                                                                              .getColumnName().getColumnNameOnly());
18829                                                                                columnName.setString(resultColumn.getName() + "."
18830                                                                                                + dataType.getTypeOfList().getColumnDefList().getColumn(j)
18831                                                                                                .getColumnName().getColumnNameOnly());
18832                                                                        }
18833                                                                        else {
18834                                                                                columnName.setString(resultColumn.getName() + "."
18835                                                                                                + dataType.getTypeOfList().getColumnDefList().getColumn(j)
18836                                                                                                                .getColumnName().getColumnNameOnly());
18837                                                                        }
18838                                                                        ResultColumn sturctColumn = modelFactory.createResultColumn(resultSet, columnName,
18839                                                                                        true);
18840                                                                        sturctColumn.setStruct(true);
18841                                                                        Function sourceFunction = (Function)createFunction(functionCall);
18842                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18843                                                                        relation.setEffectType(effectType);
18844                                                                        relation.setTarget(new ResultColumnRelationshipElement(sturctColumn));
18845                                                                        if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) {
18846                                                                                for (ResultColumn column : sourceFunction.getColumns()) {
18847                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
18848                                                                                }
18849                                                                        }
18850                                                                }
18851                                                                resultSet.getColumns().remove(resultColumn);
18852                                                        }
18853                                                        return;
18854                                                }
18855                                        }
18856                                }
18857                        }
18858                        
18859                        if(gspObject instanceof TResultColumn) {
18860                                TResultColumn resultColumn = (TResultColumn)gspObject;
18861                                if(resultColumn.getAliasClause()!=null && resultColumn.getAliasClause().getColumns()!=null) {
18862                                        for(TObjectName columnName: resultColumn.getAliasClause().getColumns()) {
18863                                                analyzeFunctionDataFlowRelation(columnName, Arrays.asList(functionCall), effectType, null);
18864                                        }
18865                                        return;
18866                                }
18867                        }
18868                        analyzeFunctionDataFlowRelation(gspObject, Arrays.asList(functionCall), effectType, null);
18869                }
18870        }
18871
18872        private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions,
18873                        EffectType effectType, Process process) {
18874
18875                Object modelObject = modelManager.getModel(gspObject);
18876                if (modelObject == null) {
18877                        if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) {
18878                                modelObject = gspObject;
18879                        }
18880                }
18881
18882                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18883                relation.setEffectType(effectType);
18884                relation.setProcess(process);
18885
18886                if (modelObject instanceof ResultColumn) {
18887                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
18888
18889                } else if (modelObject instanceof TableColumn) {
18890                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
18891
18892                } else {
18893                        throw new UnsupportedOperationException();
18894                }
18895
18896                for (int i = 0; i < functions.size(); i++) {
18897                        TParseTreeNode functionCall = functions.get(i);
18898
18899                        if (functionCall instanceof TFunctionCall) {
18900                                TFunctionCall call = (TFunctionCall) functionCall;
18901                                Procedure callee = modelManager.getProcedureByName(
18902                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call)));
18903                                if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(call))) {
18904                                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(call)));
18905                                        callee = modelManager.getProcedureByName(
18906                                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call)));
18907                                }
18908
18909                                if (callee != null) {
18910                                        String procedureParent = getProcedureParentName(stmtStack.peek());
18911                                        if (procedureParent != null) {
18912                                                Procedure caller = modelManager
18913                                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
18914                                                if (caller != null) {
18915                                                        CallRelationship callRelation = modelFactory.createCallRelation();
18916                                                        callRelation.setCallObject(functionCall);
18917                                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
18918                                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
18919                                                        if (isBuiltInFunctionName(call.getFunctionName()) || isKeyword(call.getFunctionName())) {
18920                                                                callRelation.setBuiltIn(true);
18921                                                        }
18922                                                }
18923                                        }
18924                                        if (callee.getArguments() != null) {
18925                                                for (int j = 0; j < callee.getArguments().size(); j++) {
18926                                                        Argument argument = callee.getArguments().get(j);
18927                                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
18928                                                        if(variable!=null) {
18929                                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
18930                                                                        Transform transform = new Transform();
18931                                                                        transform.setType(Transform.FUNCTION);
18932                                                                        transform.setCode(call);
18933                                                                        variable.getColumns().get(0).setTransform(transform);
18934                                                                }
18935                                                                Process callProcess = modelFactory.createProcess(call);
18936                                                                variable.addProcess(callProcess);
18937                                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), call, j, callProcess);
18938                                                        }
18939                                                }
18940                                        }
18941                                        Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
18942                                                        .getIdentifierNormalTableName(call.getFunctionName().toString()));
18943                                        if (functionTableModelObjs != null) {
18944                                                modelManager.bindModel(call, functionTableModelObjs.iterator().next());
18945                                                for (Object functionTableModelObj : functionTableModelObjs) {
18946                                                        if (functionTableModelObj instanceof ResultSet) {
18947                                                                ResultSet resultSet = (ResultSet) functionTableModelObj;
18948                                                                for (ResultColumn column : resultSet.getColumns()) {
18949                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
18950                                                                }
18951                                                        }
18952                                                }
18953                                        }
18954                                        continue;
18955                                }
18956                        }
18957
18958
18959                        Object functionModel = createFunction(functionCall);
18960                        if (functionModel instanceof Function) {
18961                                Function sourceFunction = (Function)functionModel;
18962                                if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) {
18963                                        for (ResultColumn column : sourceFunction.getColumns()) {
18964                                                relation.addSource(new ResultColumnRelationshipElement(column));
18965                                        }
18966                                }
18967                                else if (functionCall instanceof TFunctionCall) {
18968                                        relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager
18969                                                        .getModel(((TFunctionCall) functionCall).getFunctionName())));
18970                                } else if (functionCall instanceof TCaseExpression) {
18971                                        relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager
18972                                                        .getModel(((TCaseExpression) functionCall).getWhenClauseItemList())));
18973                                }
18974                                
18975                                if (sourceFunction != null && !sourceFunction.getRelationRows().getHoldRelations().isEmpty()) {
18976                                        boolean find = false;
18977                                        if (modelObject instanceof ResultColumn) {
18978                                                ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows();
18979                                                if(targetRelationRows.hasRelation()) {
18980                                                        for(Relationship relationship: targetRelationRows.getHoldRelations()) {
18981                                                                if(relationship.getSources().contains(sourceFunction.getRelationRows())) {
18982                                                                        find = true;
18983                                                                        break;
18984                                                                }
18985                                                        }
18986                                                }
18987                                        }
18988                                        else if (modelObject instanceof TableColumn) {
18989                                                TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows();
18990                                                if(targetRelationRows.hasRelation()) {
18991                                                        for(Relationship relationship: targetRelationRows.getHoldRelations()) {
18992                                                                if(relationship.getSources().contains(sourceFunction.getRelationRows())) {
18993                                                                        find = true;
18994                                                                        break;
18995                                                                }
18996                                                        }
18997                                                }
18998                                        }
18999                                        
19000                                        if (!find) {
19001                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
19002                                                impactRelation.setEffectType(EffectType.select);
19003                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19004                                                                sourceFunction.getRelationRows()));
19005                                                if (modelObject instanceof ResultColumn) {
19006                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19007                                                                        ((ResultColumn) modelObject).getResultSet().getRelationRows()));
19008                                                } else if (modelObject instanceof TableColumn) {
19009                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
19010                                                                        ((TableColumn) modelObject).getTable().getRelationRows()));
19011                                                }
19012                                        }
19013                                }
19014                        } else if (functionModel instanceof Table) {
19015                                TFunctionCall call = (TFunctionCall) functionCall;
19016                                String functionName = call.getFunctionName().toString();
19017                                boolean flag = false;
19018                                if (functionName.indexOf(".") != -1) {
19019                                        String columnName = functionName.substring(functionName.indexOf(".") + 1);
19020                                        for (TableColumn tableColumn : ((Table) functionModel).getColumns()) {
19021                                                if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) {
19022                                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
19023                                                        relation.addSource(element);
19024                                                        flag = true;
19025                                                        break;
19026                                                }
19027                                        }
19028                                }
19029
19030                                if (!flag) {
19031                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
19032                                                        ((TFunctionCall) functionCall));
19033                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
19034                                        relation.addSource(element);
19035                                }
19036                        }
19037                }
19038
19039        }
19040
19041        private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys,
19042                        EffectType effectType) {
19043                analyzeSubqueryDataFlowRelation(gspObject, subquerys, effectType, null);
19044        }
19045
19046        private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys,
19047                        EffectType effectType, Process process) {
19048
19049                Object modelObject = modelManager.getModel(gspObject);
19050                if (modelObject == null) {
19051                        if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) {
19052                                modelObject = gspObject;
19053                        }
19054                }
19055
19056                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19057                relation.setEffectType(effectType);
19058                relation.setProcess(process);
19059
19060                if (modelObject instanceof ResultColumn) {
19061                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
19062
19063                } else if (modelObject instanceof TableColumn) {
19064                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
19065
19066                } else {
19067                        throw new UnsupportedOperationException();
19068                }
19069
19070                for (int i = 0; i < subquerys.size(); i++) {
19071                        TSelectSqlStatement subquery = subquerys.get(i);
19072                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
19073                        if (resultSetModel != null && resultSetModel.getColumns() != null) {
19074                                for (ResultColumn column : resultSetModel.getColumns()) {
19075                                        relation.addSource(new ResultColumnRelationshipElement(column));
19076                                }
19077                        }
19078                        
19079                        if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
19080                                boolean find = false;
19081                                if (modelObject instanceof ResultColumn) {
19082                                        ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows();
19083                                        if(targetRelationRows.hasRelation()) {
19084                                                for(Relationship relationship: targetRelationRows.getHoldRelations()) {
19085                                                        if(relationship.getSources().contains(resultSetModel.getRelationRows())) {
19086                                                                find = true;
19087                                                                break;
19088                                                        }
19089                                                }
19090                                        }
19091                                }
19092                                else if (modelObject instanceof TableColumn) {
19093                                        TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows();
19094                                        if(targetRelationRows.hasRelation()) {
19095                                                for(Relationship relationship: targetRelationRows.getHoldRelations()) {
19096                                                        if(relationship.getSources().contains(resultSetModel.getRelationRows())) {
19097                                                                find = true;
19098                                                                break;
19099                                                        }
19100                                                }
19101                                        }
19102                                }
19103                                
19104                                if (!find) {
19105                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
19106                                        impactRelation.setEffectType(EffectType.select);
19107                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19108                                                        resultSetModel.getRelationRows()));
19109                                        if (modelObject instanceof ResultColumn) {
19110                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19111                                                                ((ResultColumn) modelObject).getResultSet().getRelationRows()));
19112                                        } else if (modelObject instanceof TableColumn) {
19113                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
19114                                                                ((TableColumn) modelObject).getTable().getRelationRows()));
19115                                        }
19116                                }
19117                        }
19118                }
19119
19120        }
19121
19122        private Object createFunction(TParseTreeNode functionCall) {
19123                if (functionCall instanceof TFunctionCall) {
19124                        TFunctionCall functionObj = (TFunctionCall) functionCall;
19125                        if (!isBuiltInFunctionName(functionObj.getFunctionName())) {
19126                                TCustomSqlStatement stmt = stmtStack.peek();
19127                                String procedureParent = getProcedureParentName(stmt);
19128                                if (procedureParent != null) {
19129                                        Procedure procedureCallee = modelManager.getProcedureByName(DlineageUtil
19130                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionObj)));
19131                                        if (procedureCallee != null) {
19132                                                if (procedureParent != null) {
19133                                                        Procedure caller = modelManager
19134                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
19135                                                        if (caller != null) {
19136                                                                CallRelationship callRelation = modelFactory.createCallRelation();
19137                                                                callRelation.setCallObject(functionCall);
19138                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
19139                                                                callRelation.addSource(new ProcedureRelationshipElement(procedureCallee));
19140                                                                if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){
19141                                                                        callRelation.setBuiltIn(true);
19142                                                                }
19143                                                        }
19144                                                }
19145                                                if (procedureCallee.getArguments() != null) {
19146                                                        for (int j = 0; j < procedureCallee.getArguments().size(); j++) {
19147                                                                Argument argument = procedureCallee.getArguments().get(j);
19148                                                                Variable variable = modelFactory.createVariable(procedureCallee, argument.getName(), false);
19149                                                                if(variable!=null) {
19150                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
19151                                                                                Transform transform = new Transform();
19152                                                                                transform.setType(Transform.FUNCTION);
19153                                                                                transform.setCode(functionObj);
19154                                                                                variable.getColumns().get(0).setTransform(transform);
19155                                                                        }
19156                                                                        Process process = modelFactory.createProcess(functionObj);
19157                                                                        variable.addProcess(process);
19158                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionObj, j, process);
19159                                                                }
19160                                                        }
19161                                                }
19162                                        } else {
19163                                                TFunctionCall call = (TFunctionCall)functionCall;
19164                                                String functionName = call.getFunctionName().toString();
19165                                                if (functionName.indexOf(".") != -1) {
19166                                                        Table functionTable = modelManager
19167                                                                        .getTableByName(functionName.substring(0, functionName.indexOf(".")));
19168                                                        if (functionTable != null) {
19169                                                                String columnName = functionName.substring(functionName.indexOf(".") + 1);
19170                                                                for (TableColumn tableColumn : functionTable.getColumns()) {
19171                                                                        if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) {
19172                                                                                return functionTable;
19173                                                                        }
19174                                                                }
19175                                                        }
19176                                                }
19177                                                Function function = modelFactory.createFunction(call);
19178                                                if (procedureParent != null) {
19179                                                        Procedure caller = modelManager
19180                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
19181                                                        if (caller != null) {
19182                                                                CallRelationship callRelation = modelFactory.createCallRelation();
19183                                                                callRelation.setCallObject(functionCall);
19184                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
19185                                                                callRelation.addSource(new FunctionRelationshipElement(function));
19186                                                                if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){
19187                                                                        callRelation.setBuiltIn(true);
19188                                                                }
19189                                                        }
19190                                                }
19191                                        }
19192                                }
19193                        } else if (isConstantFunction(functionObj.getFunctionName())
19194                                        && (functionObj.getArgs() == null || functionObj.getArgs().size() == 0)) {
19195                                if (option.isShowConstantTable()) {
19196                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
19197                                        modelFactory.createTableColumn(constantTable, functionObj);
19198                                        return constantTable;
19199                                } else {
19200                                        return null;
19201                                }
19202                        }  
19203                        
19204                        if (functionObj.getFunctionType() == EFunctionType.struct_t) {
19205                                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
19206                                if(functionObj instanceof TTableFunction) {
19207                                        TTableFunction tableFunction = (TTableFunction) functionObj;
19208                                        if (tableFunction.getFieldValues() != null) {
19209                                                for (int i = 0; i < tableFunction.getFieldValues().size(); i++) {
19210                                                        TResultColumn resultColumn = tableFunction.getFieldValues().getResultColumn(i);
19211                                                        if (resultColumn.getAliasClause() != null) {
19212                                                                ResultColumn column = modelFactory.createFunctionResultColumn(function,
19213                                                                                resultColumn.getAliasClause().getAliasName());
19214                                                                columnsInExpr visitor = new columnsInExpr();
19215                                                                resultColumn.getExpr().inOrderTraverse(visitor);
19216                                                                List<TObjectName> objectNames = visitor.getObjectNames();
19217                                                                List<TParseTreeNode> functions = visitor.getFunctions();
19218                                                                if (functions != null && !functions.isEmpty()) {
19219                                                                        analyzeFunctionDataFlowRelation(column, functions, EffectType.function);
19220                                                                }
19221                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19222                                                                if (subquerys != null && !subquerys.isEmpty()) {
19223                                                                        analyzeSubqueryDataFlowRelation(column, subquerys, EffectType.function);
19224                                                                }
19225                                                                analyzeDataFlowRelation(column, objectNames, EffectType.function, functions);
19226                                                                List<TParseTreeNode> constants = visitor.getConstants();
19227                                                                analyzeConstantDataFlowRelation(column, constants, EffectType.function, functions);
19228                                                        } else if (resultColumn.getFieldAttr() != null) {
19229                                                                ResultColumn column = modelFactory.createFunctionResultColumn(function,
19230                                                                                resultColumn.getFieldAttr());
19231                                                                analyzeDataFlowRelation(column, Arrays.asList(resultColumn.getFieldAttr()), EffectType.function, null);
19232                                                        } else if (resultColumn.getExpr() != null) {
19233                                                                if (resultColumn.getExpr().getFunctionCall() != null) {
19234                                                                        Function resultColumnFunction = (Function) createFunction(
19235                                                                                        resultColumn.getExpr().getFunctionCall());
19236                                                                        String functionName = getResultSetName(function);
19237                                                                        for (int j = 0; j < resultColumnFunction.getColumns().size(); j++) {
19238                                                                                TObjectName columnName = new TObjectName();
19239                                                                                if (resultColumn.getAliasClause() != null) {
19240                                                                                        columnName.setString(resultColumn.getAliasClause() + "." + getColumnNameOnly(
19241                                                                                                        resultColumnFunction.getColumns().get(j).getName()));
19242                                                                                } else {
19243                                                                                        columnName.setString(functionName + "." + getColumnNameOnly(
19244                                                                                                        resultColumnFunction.getColumns().get(j).getName()));
19245                                                                                }
19246                                                                                ResultColumn functionResultColumn = modelFactory.createResultColumn(function,
19247                                                                                                columnName);
19248                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
19249                                                                                relationship.setTarget(new ResultColumnRelationshipElement(functionResultColumn));
19250                                                                                relationship.addSource(new ResultColumnRelationshipElement(
19251                                                                                                resultColumnFunction.getColumns().get(j)));
19252                                                                        }
19253                                                                }
19254                                                                else if (resultColumn.getExpr().getCaseExpression() != null) {
19255                                                                        function = modelFactory.createFunction(resultColumn.getExpr().getCaseExpression());
19256                                                                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
19257                                                                                        ((TCaseExpression) resultColumn.getExpr().getCaseExpression()).getWhenClauseItemList());
19258                                                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19259                                                                }
19260                                                        }
19261                                                }
19262                                                return function;
19263                                        }
19264                                }
19265                                else if(functionObj instanceof TFunctionCall) {
19266                                        
19267                                }
19268                        }
19269                        
19270                        if (functionObj.getFunctionType() == EFunctionType.array_t || functionObj.getFunctionType() == EFunctionType.array_agg_t) {
19271                                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
19272                                if(functionObj.getArgs()!=null) {
19273                                        if(functionObj.getArgs().getExpression(0).getSubQuery()!=null) {
19274                                                TSelectSqlStatement stmt = functionObj.getArgs().getExpression(0).getSubQuery();
19275                                                analyzeSelectStmt(stmt);
19276                                                ResultSet resultset = (ResultSet) modelManager.getModel(stmt);
19277                                                for (int i = 0; i < resultset.getColumns().size(); i++) {
19278                                                        ResultColumn sourceColumn = resultset.getColumns().get(i);
19279                                                        TObjectName columnName = new TObjectName();
19280                                                        columnName.setString(sourceColumn.getName());
19281                                                        ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function,
19282                                                                        columnName);
19283                                                        DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
19284                                                        relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
19285                                                        relationship.addSource(
19286                                                                        new ResultColumnRelationshipElement(sourceColumn));
19287                                                }
19288                                                return function;
19289                                        }
19290                                        else if (functionObj.getArgs().getExpression(0).getExpressionType() == EExpressionType.function_t) {
19291                                                Object functionTableModelObj = createFunction(functionObj.getArgs().getExpression(0).getFunctionCall());
19292                                                if (functionTableModelObj instanceof ResultSet) {
19293                                                        ResultSet resultset = (ResultSet) functionTableModelObj;
19294                                                        for (int i = 0; i < resultset.getColumns().size(); i++) {
19295                                                                ResultColumn sourceColumn = resultset.getColumns().get(i);
19296                                                                TObjectName columnName = new TObjectName();
19297                                                                columnName.setString(sourceColumn.getName());
19298                                                                ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function, columnName);
19299                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
19300                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
19301                                                                relationship.addSource(new ResultColumnRelationshipElement(sourceColumn));
19302                                                        }
19303                                                        return function;
19304                                                }
19305                                        }
19306                                }
19307                        }
19308                        
19309                        Function function = modelFactory.createFunction((TFunctionCall) functionCall);
19310                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
19311                                        ((TFunctionCall) functionCall).getFunctionName());
19312                        if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) {
19313                                // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP
19314                                // COUNT特殊处理,不和参数关联
19315                                if (option.isShowCountTableColumn()) {
19316                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19317                                }
19318                        } else {
19319                                boolean isCustomFunction = analyzeCustomFunctionCall((TFunctionCall)functionCall);
19320//                              if(!isCustomFunction) 
19321                                {
19322                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19323                                }
19324                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function));
19325                                if(functionTableModelObjs!=null) {
19326                                        for(Object functionTableModelObj: functionTableModelObjs) {
19327                                                if (functionTableModelObj instanceof ResultSet) {
19328                                                        ResultSet functionTableModel = (ResultSet) functionTableModelObj;
19329                                                        if (functionTableModel.getColumns() != null) {
19330                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
19331                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19332                                                                        relation.setEffectType(EffectType.select);
19333                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
19334                                                                        relation.addSource(new ResultColumnRelationshipElement(
19335                                                                                        functionTableModel.getColumns().get(j)));
19336                                                                }
19337                                                        }
19338                                                }
19339                                        }
19340                                }
19341                        }
19342                        return function;
19343                } else if (functionCall instanceof TCaseExpression) {
19344                        Function function = modelFactory.createFunction((TCaseExpression) functionCall);
19345                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
19346                                        ((TCaseExpression) functionCall).getWhenClauseItemList());
19347                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19348                        return function;
19349                } else if (functionCall instanceof TObjectName) {
19350                        Function function = modelFactory.createFunction((TObjectName) functionCall);
19351                        TObjectName columnName = new TObjectName();
19352                        columnName.setString(function.getFunctionName());
19353                        ResultColumn column = modelFactory.createResultColumn(function,
19354                                        columnName);
19355                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19356                        return function;
19357                }
19358                return null;
19359        }
19360
19361        protected String getIdentifiedFunctionName(Function function) {
19362                return DlineageUtil.getIdentifierNormalFunctionName(function.getFunctionName());
19363        }
19364        
19365        private boolean isConstantFunction(TObjectName functionName) {
19366                boolean result = CONSTANT_BUILTIN_FUNCTIONS.contains(functionName.toString().toUpperCase());
19367                if (result) {
19368                        return true;
19369                }
19370                return false;
19371        }
19372
19373        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TParseTreeNode gspObject) {
19374                List<TExpression> directExpressions = new ArrayList<TExpression>();
19375                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19376                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19377                if (gspObject instanceof TFunctionCall) {
19378                        TFunctionCall functionCall = (TFunctionCall) gspObject;
19379                        getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
19380                } else if (gspObject instanceof TCaseExpression) {
19381                        TCaseExpression expr = (TCaseExpression) gspObject;
19382                        TExpression inputExpr = expr.getInput_expr();
19383                        if (inputExpr != null) {
19384                                if(option.isShowCaseWhenAsDirect()){
19385                                        directExpressions.add(inputExpr);
19386                                }
19387                                else {
19388                                        conditionExpressions.add(inputExpr);
19389                                }
19390                        }
19391                        TExpression defaultExpr = expr.getElse_expr();
19392                        if (defaultExpr != null) {
19393                                directExpressions.add(defaultExpr);
19394                        }
19395                        TWhenClauseItemList list = expr.getWhenClauseItemList();
19396                        for (int i = 0; i < list.size(); i++) {
19397                                TWhenClauseItem element = list.getWhenClauseItem(i);
19398                                if(option.isShowCaseWhenAsDirect()){
19399                                        directExpressions.add(element.getComparison_expr());
19400                                }
19401                                else {
19402                                        conditionExpressions.add(element.getComparison_expr());
19403                                }
19404                                directExpressions.add(element.getReturn_expr());
19405                        }
19406                }
19407
19408                for (int j = 0; j < directExpressions.size(); j++) {
19409                        columnsInExpr visitor = new columnsInExpr();
19410                        directExpressions.get(j).inOrderTraverse(visitor);
19411
19412                        List<TObjectName> objectNames = visitor.getObjectNames();
19413                        List<TParseTreeNode> functions = visitor.getFunctions();
19414
19415                        if (functions != null && !functions.isEmpty()) {
19416                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19417                        }
19418
19419                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19420                        if (subquerys != null && !subquerys.isEmpty()) {
19421                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19422                        }
19423
19424                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19425
19426                        List<TParseTreeNode> constants = visitor.getConstants();
19427                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19428                }
19429
19430                conditionExpressions.addAll(indirectExpressions);
19431                for (int j = 0; j < conditionExpressions.size(); j++) {
19432                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19433                }
19434        }
19435        
19436        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TCallStatement callStatment, int argumentIndex, Process process) {
19437                List<TExpression> directExpressions = new ArrayList<TExpression>();
19438                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19439                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19440
19441                getFunctionExpressions(directExpressions, indirectExpressions, callStatment, argumentIndex);
19442
19443                for (int j = 0; j < directExpressions.size(); j++) {
19444                        columnsInExpr visitor = new columnsInExpr();
19445                        directExpressions.get(j).inOrderTraverse(visitor);
19446
19447                        List<TObjectName> objectNames = visitor.getObjectNames();
19448                        List<TParseTreeNode> functions = visitor.getFunctions();
19449
19450                        if (functions != null && !functions.isEmpty()) {
19451                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19452                        }
19453
19454                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19455                        if (subquerys != null && !subquerys.isEmpty()) {
19456                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19457                        }
19458
19459                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19460                        if (relation != null) {
19461                                relation.setProcess(process);
19462                        }
19463
19464                        List<TParseTreeNode> constants = visitor.getConstants();
19465                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19466                }
19467
19468                conditionExpressions.addAll(indirectExpressions);
19469                for (int j = 0; j < conditionExpressions.size(); j++) {
19470                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19471                }
19472        }
19473
19474        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TFunctionCall functionCall, int argumentIndex, Process process) {
19475                List<TExpression> directExpressions = new ArrayList<TExpression>();
19476                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19477                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19478
19479                getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentIndex);
19480
19481                for (int j = 0; j < directExpressions.size(); j++) {
19482                        columnsInExpr visitor = new columnsInExpr();
19483                        directExpressions.get(j).inOrderTraverse(visitor);
19484
19485                        List<TObjectName> objectNames = visitor.getObjectNames();
19486                        List<TParseTreeNode> functions = visitor.getFunctions();
19487
19488                        if (functions != null && !functions.isEmpty()) {
19489                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19490                        }
19491
19492                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19493                        if (subquerys != null && !subquerys.isEmpty()) {
19494                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19495                        }
19496
19497                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19498                        if (relation != null) {
19499                                relation.setProcess(process);
19500                        }
19501
19502                        List<TParseTreeNode> constants = visitor.getConstants();
19503                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19504                }
19505
19506                conditionExpressions.addAll(indirectExpressions);
19507                for (int j = 0; j < conditionExpressions.size(); j++) {
19508                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19509                }
19510        }
19511
19512        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TMssqlExecute functionCall, String argumentName, int argumentIndex, Process process) {
19513                List<TExpression> directExpressions = new ArrayList<TExpression>();
19514                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19515                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19516
19517                getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentName, argumentIndex);
19518
19519                for (int j = 0; j < directExpressions.size(); j++) {
19520                        columnsInExpr visitor = new columnsInExpr();
19521                        directExpressions.get(j).inOrderTraverse(visitor);
19522
19523                        List<TObjectName> objectNames = visitor.getObjectNames();
19524                        List<TParseTreeNode> functions = visitor.getFunctions();
19525
19526                        if (functions != null && !functions.isEmpty()) {
19527                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19528                        }
19529
19530                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19531                        if (subquerys != null && !subquerys.isEmpty()) {
19532                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19533                        }
19534
19535                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19536                        if (relation != null) {
19537                                relation.setProcess(process);
19538                        }
19539
19540                        List<TParseTreeNode> constants = visitor.getConstants();
19541                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19542                }
19543
19544                conditionExpressions.addAll(indirectExpressions);
19545                for (int j = 0; j < conditionExpressions.size(); j++) {
19546                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19547                }
19548        }
19549
19550
19551        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
19552                        TFunctionCall functionCall) {
19553                if (functionCall.getArgs() != null) {
19554                        for (int k = 0; k < functionCall.getArgs().size(); k++) {
19555                                TExpression expr = functionCall.getArgs().getExpression(k);
19556                                if(FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(),  functionCall.getArgs().size(), k)) {
19557                                        directExpressions.add(expr);
19558                                }
19559                                if(FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(),  functionCall.getArgs().size(), k)) {
19560                                        indirectExpressions.add(expr);
19561                                }
19562                        }
19563                }
19564                if (functionCall.getXMLElementValueExprList() != null) {
19565                        for (int k = 0; k < functionCall.getXMLElementValueExprList().size(); k++) {
19566                                TExpression expr = functionCall.getXMLElementValueExprList().getResultColumn(k).getExpr();
19567                                directExpressions.add(expr);
19568                        }
19569                }
19570                if (functionCall.getTrimArgument() != null) {
19571                        TTrimArgument args = functionCall.getTrimArgument();
19572                        TExpression expr = args.getStringExpression();
19573                        if (expr != null) {
19574                                directExpressions.add(expr);
19575                        }
19576                        expr = args.getTrimCharacter();
19577                        if (expr != null) {
19578                                directExpressions.add(expr);
19579                        }
19580                }
19581
19582                if (functionCall.getAgainstExpr() != null) {
19583                        directExpressions.add(functionCall.getAgainstExpr());
19584                }
19585//              if (functionCall.getBetweenExpr() != null) {
19586//                      directExpressions.add(functionCall.getBetweenExpr());
19587//              }
19588                if (functionCall.getExpr1() != null) {
19589                        directExpressions.add(functionCall.getExpr1());
19590                }
19591                if (functionCall.getExpr2() != null) {
19592                        directExpressions.add(functionCall.getExpr2());
19593                }
19594                if (functionCall.getExpr3() != null) {
19595                        directExpressions.add(functionCall.getExpr3());
19596                }
19597                if (functionCall.getParameter() != null) {
19598                        directExpressions.add(functionCall.getParameter());
19599                }
19600                if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getPartitionClause() != null) {
19601                        TExpressionList args = functionCall.getWindowDef().getPartitionClause().getExpressionList();
19602                        if (args != null) {
19603                                for (int k = 0; k < args.size(); k++) {
19604                                        TExpression expr = args.getExpression(k);
19605                                        if (expr != null) {
19606                                                indirectExpressions.add(expr);
19607                                        }
19608                                }
19609                        }
19610                }
19611                if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getOrderBy() != null) {
19612                        TOrderByItemList orderByList = functionCall.getWindowDef().getOrderBy().getItems();
19613                        for (int i = 0; i < orderByList.size(); i++) {
19614                                TOrderByItem element = orderByList.getOrderByItem(i);
19615                                TExpression expression = element.getSortKey();
19616                                indirectExpressions.add(expression);
19617                        }
19618                }
19619                if (functionCall.getWithinGroup() != null && functionCall.getWithinGroup().getOrderBy() != null) {
19620                        TOrderByItemList orderByList = functionCall.getWithinGroup().getOrderBy().getItems();
19621                        for (int i = 0; i < orderByList.size(); i++) {
19622                                TOrderByItem element = orderByList.getOrderByItem(i);
19623                                TExpression expression = element.getSortKey();
19624                                indirectExpressions.add(expression);
19625                        }
19626                }
19627                if (functionCall.getCallTarget() != null) {
19628                        directExpressions.add(functionCall.getCallTarget().getExpr());
19629                }
19630                if (functionCall.getFieldValues() != null) {
19631                        for (int k = 0; k < functionCall.getFieldValues().size(); k++) {
19632                                TExpression expr = functionCall.getFieldValues().getResultColumn(k).getExpr();
19633                                directExpressions.add(expr);
19634                        }
19635                }
19636                if (functionCall instanceof TJsonObjectFunction) {
19637                        TJsonObjectFunction jsonObject = (TJsonObjectFunction)functionCall;
19638                        for (int k = 0; k < jsonObject.getKeyValues().size(); k++) {
19639                                TExpression expr = jsonObject.getKeyValues().get(k).getValue();
19640                                directExpressions.add(expr);
19641                        }
19642                }
19643        }
19644
19645        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
19646                                                                                TFunctionCall functionCall, int argumentIndex) {
19647                if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) {
19648                        TExpression expr = functionCall.getArgs().getExpression(argumentIndex);
19649                        if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) {
19650                                directExpressions.add(expr);
19651                        }
19652                        if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) {
19653                                indirectExpressions.add(expr);
19654                        }
19655                }
19656        }
19657        
19658        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
19659                        TCallStatement functionCall, int argumentIndex) {
19660                if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) {
19661                        TExpression expr = functionCall.getArgs().getExpression(argumentIndex);
19662                        if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getRoutineName().toString(),
19663                                        functionCall.getArgs().size(), argumentIndex)) {
19664                                directExpressions.add(expr);
19665                        }
19666                        if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getRoutineName().toString(),
19667                                        functionCall.getArgs().size(), argumentIndex)) {
19668                                indirectExpressions.add(expr);
19669                        }
19670                }
19671        }
19672
19673        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
19674                                                                                TMssqlExecute functionCall, String argumentName, int argumentIndex) {
19675                if (functionCall.getParameters() != null) {
19676                        for (int i = 0; i < functionCall.getParameters().size(); i++) {
19677                                TExecParameter param = functionCall.getParameters().getExecParameter(i);
19678                                if (param.getParameterName() != null) {
19679                                        if (DlineageUtil.compareColumnIdentifier(param.getParameterName().toString(), argumentName)) {
19680                                                TExpression expr = param.getParameterValue();
19681                                                directExpressions.add(expr);
19682                                        }
19683                                } else if (i == argumentIndex) {
19684                                        TExpression expr = param.getParameterValue();
19685                                        directExpressions.add(expr);
19686                                }
19687                        }
19688                }
19689        }
19690
19691        private void analyzeJoin(TJoin join, EffectType effectType) {
19692                if (join.getJoinItems() != null) {
19693                        for (int j = 0; j < join.getJoinItems().size(); j++) {
19694                                TJoinItem joinItem = join.getJoinItems().getJoinItem(j);
19695                                TExpression expr = joinItem.getOnCondition();
19696                                if (expr != null) {
19697                                        analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on, effectType);
19698                                }
19699                        }
19700                }
19701
19702                if (join.getJoin() != null) {
19703                        analyzeJoin(join.getJoin(), effectType);
19704                }
19705        }
19706
19707        private TSelectSqlStatement getParentSetSelectStmt(TSelectSqlStatement stmt) {
19708                TCustomSqlStatement parent = stmt.getParentStmt();
19709                if (parent == null)
19710                        return null;
19711                if (parent.getStatements() != null) {
19712                        for (int i = 0; i < parent.getStatements().size(); i++) {
19713                                TCustomSqlStatement temp = parent.getStatements().get(i);
19714                                if (temp instanceof TSelectSqlStatement) {
19715                                        TSelectSqlStatement select = (TSelectSqlStatement) temp;
19716                                        if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt)
19717                                                return select;
19718                                }
19719                        }
19720                }
19721                if (parent instanceof TSelectSqlStatement) {
19722                        TSelectSqlStatement select = (TSelectSqlStatement) parent;
19723                        if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt)
19724                                return select;
19725                }
19726                return null;
19727        }
19728
19729        private void createSelectSetResultColumns(SelectSetResultSet resultSet, TSelectSqlStatement stmt) {
19730                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
19731                        createSelectSetResultColumns(resultSet, stmt.getLeftStmt());
19732                } else {
19733                        TResultColumnList columnList = stmt.getResultColumnList();
19734                        ResultSet subqueryResultSet = (ResultSet) modelManager.getModel(columnList);
19735                        if(subqueryResultSet!=null && subqueryResultSet.isDetermined()) {
19736                                for (int j = 0; j < subqueryResultSet.getColumns().size(); j++) {
19737                                        ResultColumn tableColumn = subqueryResultSet.getColumns().get(j);
19738                                        if (tableColumn.getRefColumnName() != null) {
19739                                                TObjectName columnName = new TObjectName();
19740                                                columnName.setString(tableColumn.getRefColumnName());
19741                                                modelFactory.createDeterminedResultColumn(
19742                                                                resultSet, columnName);
19743                                        } else {
19744                                                TObjectName columnName = new TObjectName();
19745                                                columnName.setString(tableColumn.getName());
19746                                                modelFactory.createDeterminedResultColumn(
19747                                                                resultSet, columnName);
19748                                        }
19749                                }
19750                                resultSet.setDetermined(true);
19751                                return;
19752                        }
19753                        
19754                        boolean isDetermined = true;
19755                        for (int i = 0; i < columnList.size(); i++) {
19756                                TResultColumn column = columnList.getResultColumn(i);
19757                                
19758                                if ("*".equals(column.getColumnNameOnly())) {
19759                                        TObjectName columnObject = column.getFieldAttr();
19760                                        TTable sourceTable = columnObject.getSourceTable();
19761                                        if (sourceTable != null) {
19762                                                Object tableModel = modelManager.getModel(sourceTable);
19763                                                if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
19764                                                        Table table = (Table) tableModel;
19765                                                        for (int j = 0; j < table.getColumns().size(); j++) {
19766                                                                TableColumn tableColumn = table.getColumns().get(j);
19767                                                                if (column.getExceptColumnList() != null) {
19768                                                                        boolean except = false;
19769                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
19770                                                                                if (getColumnName(objectName.toString())
19771                                                                                                .equals(getColumnName(tableColumn.getName()))) {
19772                                                                                        except = true;
19773                                                                                        break;
19774                                                                                }
19775                                                                        }
19776                                                                        if (!except && tableColumn.isStruct()) {
19777                                                                                List<String> names = SQLUtil
19778                                                                                                .parseNames(tableColumn.getName());
19779                                                                                for (String name : names) {
19780                                                                                        for (TObjectName objectName : column
19781                                                                                                        .getExceptColumnList()) {
19782                                                                                                if (getColumnName(objectName.toString())
19783                                                                                                                .equals(getColumnName(name))) {
19784                                                                                                        except = true;
19785                                                                                                        break;
19786                                                                                                }
19787                                                                                        }
19788                                                                                        if (except) {
19789                                                                                                break;
19790                                                                                        }
19791                                                                                }
19792                                                                        }
19793                                                                        if (except) {
19794                                                                                continue;
19795                                                                        }
19796                                                                }
19797                                                                TObjectName columnName = new TObjectName();
19798                                                                columnName.setString(tableColumn.getName());
19799                                                                ResultColumn resultColumn = modelFactory.createResultColumn(
19800                                                                                resultSet, columnName);
19801                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19802                                                                relation.setEffectType(EffectType.select);
19803                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19804                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
19805                                                        }
19806                                                        continue;
19807                                                } else if (tableModel instanceof ResultSet
19808                                                                && ((ResultSet) tableModel).isDetermined()) {
19809                                                        ResultSet table = (ResultSet) tableModel;
19810                                                        for (int j = 0; j < table.getColumns().size(); j++) {
19811                                                                ResultColumn tableColumn = table.getColumns().get(j);
19812                                                                if (column.getExceptColumnList() != null) {
19813                                                                        boolean except = false;
19814                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
19815                                                                                if (getColumnName(objectName.toString())
19816                                                                                                .equals(getColumnName(tableColumn.getName()))) {
19817                                                                                        except = true;
19818                                                                                        break;
19819                                                                                }
19820                                                                        }
19821                                                                        if (!except && tableColumn.isStruct()) {
19822                                                                                List<String> names = SQLUtil
19823                                                                                                .parseNames(tableColumn.getName());
19824                                                                                for (String name : names) {
19825                                                                                        for (TObjectName objectName : column
19826                                                                                                        .getExceptColumnList()) {
19827                                                                                                if (getColumnName(objectName.toString())
19828                                                                                                                .equals(getColumnName(name))) {
19829                                                                                                        except = true;
19830                                                                                                        break;
19831                                                                                                }
19832                                                                                        }
19833                                                                                        if (except) {
19834                                                                                                break;
19835                                                                                        }
19836                                                                                }
19837                                                                        }
19838                                                                        if (except) {
19839                                                                                continue;
19840                                                                        }
19841                                                                }
19842                                                                if (tableColumn.getRefColumnName() != null) {
19843                                                                        TObjectName columnName = new TObjectName();
19844                                                                        columnName.setString(tableColumn.getRefColumnName());
19845                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(
19846                                                                                        resultSet, columnName);
19847                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19848                                                                        relation.setEffectType(EffectType.select);
19849                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19850                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19851                                                                } else {
19852                                                                        TObjectName columnName = new TObjectName();
19853                                                                        columnName.setString(tableColumn.getName());
19854                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(
19855                                                                                        resultSet, columnName);
19856                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19857                                                                        relation.setEffectType(EffectType.select);
19858                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19859                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19860                                                                }
19861                                                        }
19862                                                        continue;
19863                                                }
19864                                                else {
19865                                                        isDetermined = false;
19866                                                }
19867                                        }
19868                                }
19869                                        
19870                                ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
19871
19872                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
19873                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
19874                                        if (columnObject.getFieldAttr() != null) {
19875                                                if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
19876                                                        TObjectName fieldAttr = columnObject.getFieldAttr();
19877                                                        TTable sourceTable = fieldAttr.getSourceTable();
19878                                                        if (fieldAttr.getTableToken() != null && sourceTable != null) {
19879                                                                TObjectName[] columns = modelManager.getTableColumns(sourceTable);
19880                                                                for (int j = 0; j < columns.length; j++) {
19881                                                                        TObjectName columnName = columns[j];
19882                                                                        if (columnName == null) {
19883                                                                                continue;
19884                                                                        }
19885                                                                        if ("*".equals(getColumnName(columnName))) {
19886                                                                                continue;
19887                                                                        }
19888                                                                        resultColumn.bindStarLinkColumn(columnName);
19889                                                                }
19890
19891                                                                if (modelManager.getModel(sourceTable) instanceof Table) {
19892                                                                        Table tableModel = (Table) modelManager.getModel(sourceTable);
19893                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19894                                                                                for (int z = 0; z < tableModel.getColumns().size(); z++) {
19895                                                                                        if ("*".equals(
19896                                                                                                        getColumnName(tableModel.getColumns().get(z).getColumnObject()))) {
19897                                                                                                continue;
19898                                                                                        }
19899                                                                                        resultColumn.bindStarLinkColumn(
19900                                                                                                        tableModel.getColumns().get(z).getColumnObject());
19901                                                                                }
19902                                                                        }
19903                                                                } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
19904                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
19905                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19906                                                                                for (ResultColumn item : tableModel.getColumns()) {
19907                                                                                        if (item.hasStarLinkColumn()) {
19908                                                                                                for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
19909                                                                                                        if ("*".equals(getColumnName(starLinkColumn))) {
19910                                                                                                                continue;
19911                                                                                                        }
19912                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
19913                                                                                                }
19914                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
19915                                                                                                TObjectName starLinkColumn = (TObjectName) item.getColumnObject();
19916                                                                                                if ("*".equals(getColumnName(starLinkColumn))) {
19917                                                                                                        continue;
19918                                                                                                }
19919                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
19920                                                                                        }
19921                                                                                }
19922                                                                        }
19923                                                                }
19924
19925                                                        } else {
19926                                                                TTableList tables = stmt.getTables();
19927                                                                for (int k = 0; k < tables.size(); k++) {
19928                                                                        TTable tableElement = tables.getTable(k);
19929                                                                        TObjectName[] columns = modelManager.getTableColumns(tableElement);
19930                                                                        for (int j = 0; j < columns.length; j++) {
19931                                                                                TObjectName columnName = columns[j];
19932                                                                                if (columnName == null) {
19933                                                                                        continue;
19934                                                                                }
19935                                                                                if ("*".equals(getColumnName(columnName))) {
19936                                                                                        if (modelManager.getModel(tableElement) instanceof Table) {
19937                                                                                                Table tableModel = (Table) modelManager.getModel(tableElement);
19938                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19939                                                                                                        for (int z = 0; z < tableModel.getColumns().size(); z++) {
19940                                                                                                                resultColumn.bindStarLinkColumn(
19941                                                                                                                                tableModel.getColumns().get(z).getColumnObject());
19942                                                                                                        }
19943                                                                                                }
19944                                                                                        } else if (modelManager.getModel(tableElement) instanceof QueryTable) {
19945                                                                                                QueryTable tableModel = (QueryTable) modelManager
19946                                                                                                                .getModel(tableElement);
19947                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19948                                                                                                        for (ResultColumn item : tableModel.getColumns()) {
19949                                                                                                                if (item.hasStarLinkColumn()) {
19950                                                                                                                        for (TObjectName starLinkColumn : item
19951                                                                                                                                        .getStarLinkColumnList()) {
19952                                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
19953                                                                                                                        }
19954                                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
19955                                                                                                                        resultColumn.bindStarLinkColumn(
19956                                                                                                                                        (TObjectName) item.getColumnObject());
19957                                                                                                                }
19958                                                                                                        }
19959                                                                                                }
19960                                                                                        }
19961                                                                                        continue;
19962                                                                                }
19963                                                                                resultColumn.bindStarLinkColumn(columnName);
19964                                                                        }
19965                                                                }
19966                                                        }
19967                                                }
19968                                        }
19969                                }
19970                                
19971                                resultSet.setDetermined(isDetermined);
19972                        }
19973                }
19974        }
19975
19976        private void analyzeResultColumn(TResultColumn column, EffectType effectType) {
19977                TExpression expression = column.getExpr();
19978                if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
19979                        expression = expression.getRightOperand();
19980                }
19981
19982                if (expression.getExpressionType() == EExpressionType.array_t) {
19983                        if (expression.getExprList() != null) {
19984                                for (TExpression expr : expression.getExprList()) {
19985                                        columnsInExpr visitor = new columnsInExpr();
19986                                        expr.inOrderTraverse(visitor);
19987                                        List<TObjectName> objectNames = visitor.getObjectNames();
19988
19989                                        List<TParseTreeNode> functions = visitor.getFunctions();
19990
19991                                        if (functions != null && !functions.isEmpty()) {
19992                                                analyzeFunctionDataFlowRelation(column, functions, effectType);
19993                                        }
19994
19995                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19996                                        if (subquerys != null && !subquerys.isEmpty()) {
19997                                                analyzeSubqueryDataFlowRelation(column, subquerys, effectType);
19998                                        }
19999
20000                                        analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions);
20001
20002                                        List<TParseTreeNode> constants = visitor.getConstants();
20003                                        Object columnObject = modelManager.getModel(column);
20004                                        analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions);
20005
20006                                        analyzeRecordSetRelation(functions, effectType);
20007                                        // analyzeResultColumnImpact( column, effectType, functions);
20008                                }
20009                        }
20010                        else {
20011                                List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
20012                                TConstant constant = new TConstant();
20013                                constant.setString(expression.toString());
20014                                constants.add(constant);
20015                                Object columnObject = modelManager.getModel(column);
20016                                analyzeConstantDataFlowRelation(columnObject, constants, effectType, null);
20017                        }
20018                } else {
20019                        columnsInExpr visitor = new columnsInExpr();
20020                        expression.inOrderTraverse(visitor);
20021                        List<TObjectName> objectNames = visitor.getObjectNames();
20022
20023                        List<TParseTreeNode> functions = visitor.getFunctions();
20024
20025                        if (functions != null && !functions.isEmpty()) {
20026                                analyzeFunctionDataFlowRelation(column, functions, effectType);
20027                        }
20028
20029                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
20030                        if (subquerys != null && !subquerys.isEmpty()) {
20031                                analyzeSubqueryDataFlowRelation(column, subquerys, effectType);
20032                        }
20033
20034                        analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions);
20035
20036                        List<TParseTreeNode> constants = visitor.getConstants();
20037                        Object columnObject = modelManager.getModel(column);
20038                        analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions);
20039
20040                        analyzeRecordSetRelation(functions, effectType);
20041                        // analyzeResultColumnImpact( column, effectType, functions);
20042                }
20043        }
20044        
20045        
20046        private void analyzeValueColumn(Object object, TResultColumn column, EffectType effectType) {
20047                TExpression expression = column.getExpr();
20048                if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
20049                        expression = expression.getRightOperand();
20050                }
20051
20052                if (expression.getExpressionType() == EExpressionType.array_t) {
20053                        if (expression.getExprList() != null) {
20054                                for (TExpression expr : expression.getExprList()) {
20055                                        columnsInExpr visitor = new columnsInExpr();
20056                                        expr.inOrderTraverse(visitor);
20057                                        List<TObjectName> objectNames = visitor.getObjectNames();
20058                                        analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null);
20059                                        List<TParseTreeNode> constants = visitor.getConstants();
20060                                        analyzeConstantDataFlowRelation(object, constants, effectType, null);
20061                                }
20062                        }
20063                        else {
20064                                List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
20065                                TConstant constant = new TConstant();
20066                                constant.setString(expression.toString());
20067                                constants.add(constant);
20068                                Object columnObject = modelManager.getModel(column);
20069                                analyzeConstantDataFlowRelation(object, constants, effectType, null);
20070                        }
20071                } else {
20072                        columnsInExpr visitor = new columnsInExpr();
20073                        expression.inOrderTraverse(visitor);
20074                        List<TObjectName> objectNames = visitor.getObjectNames();
20075                        analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null);
20076                        List<TParseTreeNode> constants = visitor.getConstants();
20077                        analyzeConstantDataFlowRelation(object, constants, effectType, null);           }
20078        }
20079
20080        private void analyzeTableColumn(TableColumn tableColumn, TFunctionCall functionCall, EffectType effectType) {
20081                List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>();
20082                functions.add(functionCall);
20083
20084                if (functions != null && !functions.isEmpty()) {
20085                        analyzeFunctionDataFlowRelation(tableColumn, functions, effectType);
20086                }
20087
20088                analyzeRecordSetRelation(functions, effectType);
20089        }
20090
20091        private void analyzeRecordSetRelation(List<TParseTreeNode> functions, EffectType effectType) {
20092                if (functions == null || functions.size() == 0)
20093                        return;
20094
20095                List<TFunctionCall> aggregateFunctions = new ArrayList<TFunctionCall>();
20096                for (TParseTreeNode function : functions) {
20097                        if (function instanceof TFunctionCall && isAggregateFunction((TFunctionCall) function)) {
20098                                aggregateFunctions.add((TFunctionCall) function);
20099                        }
20100                }
20101
20102                if (aggregateFunctions.size() == 0)
20103                        return;
20104
20105                for (int i = 0; i < aggregateFunctions.size(); i++) {
20106                        TFunctionCall function = aggregateFunctions.get(i);
20107
20108                        TCustomSqlStatement stmt = stmtStack.peek();
20109                        if (stmt instanceof TSelectSqlStatement) {
20110                                TSelectSqlStatement select = (TSelectSqlStatement) stmt;
20111                                if (select.getGroupByClause() != null) {
20112                                        TGroupByItemList groupByList = select.getGroupByClause().getItems();
20113                                        for (int j = 0; j < groupByList.size(); j++) {
20114                                                TGroupByItem groupBy = groupByList.getGroupByItem(j);
20115                                                TExpression expr = groupBy.getExpr();
20116                                                analyzeAggregate(function, expr);
20117                                        }
20118
20119                                        if (select.getGroupByClause().getHavingClause() != null) {
20120                                                analyzeAggregate(function, select.getGroupByClause().getHavingClause());
20121                                        }
20122                                        // if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString()))
20123                                        {
20124                                                analyzeAggregate(function, null);
20125                                        }
20126                                } else {
20127                                        analyzeAggregate(function, null);
20128                                }
20129                        }
20130                }
20131        }
20132
20133        private void analyzeDataFlowRelation(TParseTreeNode gspObject, List<TObjectName> objectNames,
20134                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions) {
20135                Object columnObject = modelManager.getModel(gspObject);
20136                analyzeDataFlowRelation(columnObject, objectNames, exceptColumnList, effectType, functions, null);
20137        }
20138
20139        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType,
20140                        List<TParseTreeNode> functions) {
20141                return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, null);
20142        }
20143        
20144        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType,
20145                        List<TParseTreeNode> functions, Process process) {
20146                return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, process);
20147        }
20148
20149        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames,
20150                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process) {
20151                return analyzeDataFlowRelation(modelObject, objectNames, exceptColumnList, effectType, functions, process, null);
20152        }
20153        
20154        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames,
20155                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process, Integer valueIndex) {
20156                if (objectNames == null || objectNames.size() == 0)
20157                        return null;
20158
20159                boolean isStar = false;
20160                boolean showStar = false;
20161
20162                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
20163                relation.setEffectType(effectType);
20164                relation.setProcess(process);
20165
20166                if (functions != null && !functions.isEmpty()) {
20167                        relation.setFunction(getFunctionName(functions.get(0)));
20168                }
20169
20170                int columnIndex = -1;
20171
20172                boolean isOut = false;
20173
20174                if (modelObject instanceof ResultColumn) {
20175                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
20176
20177                        if ("*".equals(((ResultColumn) modelObject).getName())) {
20178                                isStar = true;
20179                                showStar = ((ResultColumn) modelObject).isShowStar();
20180                        }
20181
20182                        if (((ResultColumn) modelObject).getResultSet() != null) {
20183                                columnIndex = ((ResultColumn) modelObject).getResultSet().getColumns().indexOf(modelObject);
20184                        }
20185                } else if (modelObject instanceof TableColumn) {
20186                        Table table  = ((TableColumn) modelObject).getTable();
20187                        if(table.getSubType() == SubType.out && isNotInProcedure(table)){
20188                                isOut = true;
20189                                relation.addSource(new TableColumnRelationshipElement((TableColumn) modelObject));
20190                        }
20191                        else {
20192                                relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
20193                        }
20194
20195                        if ("*".equals(((TableColumn) modelObject).getName())) {
20196                                isStar = true;
20197                        }
20198
20199                        if (((TableColumn) modelObject).getTable() != null) {
20200                                columnIndex = ((TableColumn) modelObject).getTable().getColumns().indexOf(modelObject);
20201                        }
20202                } else {
20203                        throw new UnsupportedOperationException();
20204                }
20205
20206                for (int i = 0; i < objectNames.size(); i++) {
20207                        TObjectName columnName = objectNames.get(i);
20208                        if (columnName.toString().indexOf(".") == -1 && isConstant(columnName)) {
20209                                boolean isConstant = true;
20210                                if (columnName.getSourceTable() != null) {
20211                                        Table tableModel = modelManager.getTableByName(
20212                                                        DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString()));
20213                                        if (tableModel != null && tableModel.getColumns() != null) {
20214                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
20215                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
20216                                                                        getColumnName(tableModel.getColumns().get(j).getName()))) {
20217                                                                isConstant = false;
20218                                                                break;
20219                                                        }
20220                                                }
20221                                        }
20222                                }
20223
20224                                if (isConstant) {
20225                                        if (option.isShowConstantTable()) {
20226                                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
20227                                                TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false);
20228                                                if(tableColumn!=null) {
20229                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20230                                                }
20231                                        }
20232                                        continue;
20233                                }
20234                        }
20235                        if (columnName.getDbObjectType() == EDbObjectType.variable) {
20236                                boolean find = false;
20237                                List<String> segments = SQLUtil.parseNames(columnName.toString());
20238                                if (segments.size() == 1) {
20239                                        Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString()));
20240                                        if (variable != null) {
20241                                                TableColumn columnModel = variable.getColumns().get(0);
20242                                                if(variable.getColumns().size()>0){
20243                                                        TableColumn matchColumn = matchColumn(variable.getColumns(), columnName);
20244                                                        if(matchColumn!=null){
20245                                                                columnModel = matchColumn;
20246                                                        }
20247                                                }
20248                                                if(isOut){
20249                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20250                                                }
20251                                                else {
20252                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20253                                                }
20254                                                find = true;
20255                                        } else {
20256                                                if (columnName.toString().matches("\\$\\d+")) {
20257                                                        TCustomSqlStatement stmt = stmtStack.peek();
20258                                                        Procedure procedure = modelManager
20259                                                                        .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt)));
20260                                                        if(procedure!=null) {
20261                                                                Variable cursorVariable = modelFactory.createVariable(procedure.getArguments().get(Integer.valueOf(columnName.toString().replace("$", "")) - 1).getName());
20262                                                                if (isOut) {
20263                                                                        relation.setTarget(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
20264                                                                } else {
20265                                                                        relation.addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
20266                                                                }
20267                                                        }
20268                                                } else {
20269                                                        Variable cursorVariable = modelFactory.createVariable(columnName);
20270                                                        cursorVariable.setCreateTable(true);
20271                                                        cursorVariable.setSubType(SubType.record);
20272                                                        TableColumn variableProperty = null;
20273                                                        if(cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
20274                                variableProperty = modelFactory.createTableColumn(cursorVariable, columnName,
20275                                        true);
20276                            }
20277                                                        else{
20278                                                                variableProperty = cursorVariable.getColumns().get(0);
20279                                                        }
20280                                                        if (isOut) {
20281                                                                relation.setTarget(new TableColumnRelationshipElement(variableProperty));
20282                                                        } else {
20283                                                                relation.addSource(new TableColumnRelationshipElement(variableProperty));
20284                                                        }
20285                                                }
20286                                                find = true;
20287                                        }
20288                                } else if (option.getVendor() == EDbVendor.dbvoracle) {
20289                                        String name = columnName.toString();
20290                                        Variable cursorVariable = modelFactory
20291                                                        .createVariable(DlineageUtil.getTableFullName(name.substring(0, name.lastIndexOf("."))));
20292
20293                                        TObjectName variableColumnName = new TObjectName();
20294                                        variableColumnName.setString(segments.get(segments.size() - 1));
20295
20296                                        if (cursorVariable.getColumns() != null) {
20297                                                for (int j = 0; j < cursorVariable.getColumns().size(); j++) {
20298                                                        if (getColumnName(variableColumnName)
20299                                                                        .equals(getColumnName(cursorVariable.getColumns().get(j).getColumnObject()))) {
20300                                                                TableColumn columnModel = cursorVariable.getColumns().get(j);
20301                                                                if (isOut) {
20302                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20303                                                                } else {
20304                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20305                                                                }
20306                                                                find = true;
20307                                                        }
20308                                                }
20309                                        }
20310
20311                                        if (!find) {
20312                                                TableColumn variableColumn = new TableColumn(cursorVariable, variableColumnName);
20313                                                cursorVariable.addColumn(variableColumn);
20314                                                if (isOut) {
20315                                                        relation.setTarget(new TableColumnRelationshipElement(variableColumn));
20316                                                } else {
20317                                                        relation.addSource(new TableColumnRelationshipElement(variableColumn));
20318                                                }
20319                                        }
20320                                } else {
20321                                        Table variable = modelManager
20322                                                        .getTableByName(DlineageUtil.getTableFullName(segments.get(segments.size() - 2)));
20323                                        if (variable != null) {
20324                                                for (int j = 0; j < variable.getColumns().size(); j++) {
20325                                                        if (getColumnName(columnName)
20326                                                                        .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) {
20327                                                                TableColumn columnModel = variable.getColumns().get(j);
20328                                                                if (isOut) {
20329                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20330                                                                } else {
20331                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20332                                                                }
20333                                                                find = true;
20334                                                        }
20335                                                }
20336                                        }
20337                                }
20338                                if (!find) {
20339                                        TCustomSqlStatement stmt = stmtStack.peek();
20340                                        if (getProcedureParentName(stmt) != null) {
20341                                                Procedure procedure = modelManager
20342                                                                .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt)));
20343                                                if (procedure != null && procedure.getArguments() != null) {
20344                                                        for (Argument argument : procedure.getArguments()) {
20345                                                                if (DlineageUtil.getTableFullName(argument.getName())
20346                                                                                .equals(DlineageUtil.getTableFullName(columnName.toString()))) {
20347                                                                        relation.addSource(new ArgumentRelationshipElement(argument));
20348                                                                }
20349                                                        }
20350                                                }
20351                                        }
20352                                }
20353                                continue;
20354                        }
20355                        
20356                        if("NEXTVAL".equalsIgnoreCase(columnName.getColumnNameOnly()) && option.getVendor() == EDbVendor.dbvoracle){
20357                                List<String> segments = SQLUtil.parseNames(columnName.toString());
20358                                segments.remove(segments.size()-1);
20359                                Table table = modelFactory.createTableByName(SQLUtil.mergeSegments(segments, 0), true);
20360                                table.setSequence(true);
20361                                TableColumn seqCursor = modelFactory.createTableColumn(table, columnName, true);
20362                                relation.addSource(new TableColumnRelationshipElement(seqCursor));
20363                                continue;
20364                        }
20365
20366                        {
20367                                if (columnName.getSourceTable() != null) {
20368
20369                                }
20370                                else {
20371                                        Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString()));
20372                                        if (variable == null) {
20373                                                variable = modelManager
20374                                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getTableString()));
20375                                                if (variable != null && variable.isCursor()) {
20376                                                        TableColumn variableColumn = modelFactory.createInsertTableColumn(variable, columnName);
20377                                                        if (variableColumn != null) {
20378                                                                if(isOut){
20379                                                                        relation.setTarget(new TableColumnRelationshipElement(variableColumn));
20380                                                                }
20381                                                                else {
20382                                                                        relation.addSource(new TableColumnRelationshipElement(variableColumn));
20383                                                                }
20384                                                        } else {
20385                                                                if(isOut){
20386                                                                        relation.setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0)));
20387                                                                }
20388                                                                else {
20389                                                                        relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0)));
20390                                                                }
20391                                                        }
20392                                                        continue;
20393                                                }
20394                                        } else if (variable.isVariable() || variable.isCursor()) {
20395                                                TableColumn columnModel = variable.getColumns().get(0);
20396                                                if (valueIndex != null) {
20397                                                        if(isOut){
20398                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel, valueIndex));
20399                                                        }
20400                                                        else {
20401                                                                relation.addSource(new TableColumnRelationshipElement(columnModel, valueIndex));
20402                                                        }
20403                                                } else {
20404                                                        if(isOut){
20405                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel));
20406                                                        }
20407                                                        else {
20408                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
20409                                                        }
20410                                                }
20411                                                continue;
20412                                        }
20413                                }
20414                        }
20415                        
20416                        if (columnName.getColumnNameOnly().startsWith("@")
20417                                        && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
20418                                continue;
20419                        }
20420
20421                        if (columnName.getColumnNameOnly().startsWith(":")
20422                                        && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
20423                                Table variable = modelManager
20424                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getColumnNameOnly().replace(":", "")));
20425                                if (variable != null) {
20426                                        for (int j = 0; j < variable.getColumns().size(); j++) {
20427                                                if (getColumnName(columnName).replace(":", "")
20428                                                                .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) {
20429                                                        TableColumn columnModel = variable.getColumns().get(j);
20430                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20431                                                }
20432                                        }
20433                                }
20434                                continue;
20435                        }
20436
20437                        boolean linkedFirstTable = false;
20438                        
20439                        TCustomSqlStatement stmt = stmtStack.peek();
20440                        TTableList tableList = stmt.tables;
20441                        if ((tableList == null || tableList.size() == 0) && (hiveFromTables != null && hiveFromTables.size() > 0)) {
20442                                tableList = hiveFromTables;
20443                        }
20444
20445                        List<TTable> tables = new ArrayList<TTable>();
20446                        {
20447                                TTable table = columnName.getSourceTable();
20448
20449                                // 针对CursorVariable特殊处理
20450                                if (columnName.getTableToken() != null) {
20451
20452                                        Table tableModel = null;
20453                                        if (table != null && modelManager.getModel(table) instanceof Table) {
20454                                                tableModel = (Table) modelManager.getModel(table);
20455                                        }
20456
20457                                        if (tableModel == null) {
20458                                                tableModel = modelManager
20459                                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getTableToken().toString()));
20460                                        }
20461
20462                                        if (tableModel == null) {
20463                                                TCustomSqlStatement currentStmt = ModelBindingManager.getGlobalStmtStack().peek();
20464                                                String procedureName = DlineageUtil.getProcedureParentName(currentStmt);
20465                                                String variableString = columnName.getTableToken().toString();
20466                                                if (variableString.startsWith(":")) {
20467                                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
20468                                                }
20469                                                if (!SQLUtil.isEmpty(procedureName)) {
20470                                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
20471                                                }
20472
20473                                                if (modelManager
20474                                                                .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
20475                                                        tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
20476                                                }
20477                                        }
20478
20479                                        if (tableModel != null) {
20480
20481                                                if (table == null) {
20482                                                        table = tableModel.getTableObject();
20483                                                }
20484
20485                                                if (tableModel.isVariable()) {
20486                                                        if (!isStar && "*".equals(getColumnName(columnName))) {
20487                                                                TObjectName[] columns = modelManager.getTableColumns(table);
20488                                                                for (int j = 0; j < columns.length; j++) {
20489                                                                        TObjectName objectName = columns[j];
20490                                                                        if (objectName == null || "*".equals(getColumnName(objectName))) {
20491                                                                                continue;
20492                                                                        }
20493                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName,
20494                                                                                        false);
20495                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20496                                                                }
20497                                                        } else {
20498                                                                if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) {
20499
20500                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
20501                                                                                TableColumn columnModel = tableModel.getColumns().get(j);
20502                                                                                if (exceptColumnList != null) {
20503                                                                                        boolean flag = false;
20504                                                                                        for (TObjectName objectName : exceptColumnList) {
20505                                                                                                if (getColumnName(objectName)
20506                                                                                                                .equals(getColumnName(columnModel.getColumnObject()))) {
20507                                                                                                        flag = true;
20508                                                                                                        break;
20509                                                                                                }
20510                                                                                        }
20511                                                                                        if (flag) {
20512                                                                                                continue;
20513                                                                                        }
20514                                                                                }
20515                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
20516                                                                        }
20517
20518                                                                        if (isStar && showStar) {
20519                                                                                TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
20520                                                                                                false);
20521                                                                                if (columnModel == null) {
20522                                                                                        if (tableModel.isCreateTable()) {
20523                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
20524                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20525                                                                                                        relation.setShowStarRelation(true);
20526                                                                                                }
20527                                                                                        }
20528                                                                                } else {
20529                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20530                                                                                        relation.setShowStarRelation(true);
20531                                                                                }
20532                                                                        }
20533                                                                } else {
20534                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
20535                                                                                        false);
20536                                                                        
20537                                                                        if(columnModel == null && containStarColumn(tableModel.getColumns())){
20538                                                                                columnModel = getStarColumn(tableModel.getColumns());
20539                                                                                if (columnModel != null && tableModel.getSubType() == SubType.record_type) {
20540                                                                                        if(!"*".equals(getColumnName(columnName))){
20541                                                                                                columnModel.bindStarLinkColumn(columnName);
20542                                                                                        }
20543                                                                                }
20544                                                                        }
20545                                                                        
20546                                                                        if (columnModel == null) {
20547                                                                                continue;
20548                                                                        }
20549                                                                        if (columnModel.hasStarLinkColumn()) {
20550                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel,
20551                                                                                                columnModel.getStarLinkColumnNames()
20552                                                                                                                .indexOf(DlineageUtil.getColumnName(columnName))));
20553                                                                        } else {
20554                                                                                if (isOut) {
20555                                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20556                                                                                } else {
20557                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20558                                                                                }
20559                                                                        }
20560                                                                        if (columnName.getSourceTable() != null
20561                                                                                        && columnName.getSourceTable().getTableType() == ETableSource.function) {
20562                                                                                analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(),
20563                                                                                                effectType);
20564                                                                        }
20565                                                                }
20566                                                        }
20567                                                        continue;
20568                                                }
20569                                        }
20570                                }
20571
20572                                if (table == null) {
20573                                        table = modelManager.getTable(stmt, columnName);
20574                                }
20575
20576                                if (table == null) {
20577                                        if (columnName.getTableToken() != null || !"*".equals(getColumnName(columnName))) {
20578                                                table = columnName.getSourceTable();
20579                                        }
20580                                        
20581                                        if (table == null && !SQLUtil.isEmpty(columnName.getTableString())) {
20582                                                table = modelManager.getTableFromColumn(columnName);
20583                                        }
20584                                }
20585
20586                                if (table == null) {
20587                                        if (tableList != null) {
20588                                                for (int j = 0; j < tableList.size(); j++) {
20589                                                        if (table != null)
20590                                                                break;
20591
20592                                                        TTable tTable = tableList.getTable(j);
20593                                                        if (tTable.getTableType().name().startsWith("open")) {
20594                                                                continue;
20595                                                        }
20596
20597                                                        if (tTable.getLinkedColumns() != null && tTable.getLinkedColumns().size() > 0) {
20598                                                                for (int z = 0; z < tTable.getLinkedColumns().size(); z++) {
20599                                                                        TObjectName refer = tTable.getLinkedColumns().getObjectName(z);
20600                                                                        if ("*".equals(getColumnName(refer)))
20601                                                                                continue;
20602                                                                        if (getColumnName(refer).equals(getColumnName(columnName))) {
20603                                                                                table = tTable;
20604                                                                                break;
20605                                                                        }
20606                                                                }
20607                                                        }
20608
20609                                                        if (tTable.getLinkTable() != null) {
20610                                                                tTable = tTable.getLinkTable();
20611                                                                for (int z = 0; z < tTable.getLinkedColumns().size(); z++) {
20612                                                                        TObjectName refer = tTable.getLinkedColumns().getObjectName(z);
20613                                                                        if ("*".equals(getColumnName(refer)))
20614                                                                                continue;
20615                                                                        if (getColumnName(refer).equals(getColumnName(columnName))) {
20616                                                                                table = tTable;
20617                                                                                break;
20618                                                                        }
20619                                                                }
20620                                                        }
20621
20622                                                        if (table != null)
20623                                                                break;
20624
20625                                                        if (columnName.getTableToken() != null && (columnName.getTableToken().getAstext()
20626                                                                        .equalsIgnoreCase(tTable.getName())
20627                                                                        || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) {
20628                                                                table = tTable;
20629                                                                break;
20630                                                        }
20631                                                }
20632                                        }
20633
20634                                        if (table == null) {
20635                                                for (int j = 0; j < tableList.size(); j++) {
20636                                                        if (table != null)
20637                                                                break;
20638
20639                                                        TTable tTable = tableList.getTable(j);
20640                                                        Object model = ModelBindingManager.get().getModel(tTable);
20641                                                        if (model instanceof Table) {
20642                                                                Table tableModel = (Table) model;
20643                                                                for (int z = 0; tableModel.getColumns() != null
20644                                                                                && z < tableModel.getColumns().size(); z++) {
20645                                                                        TableColumn refer = tableModel.getColumns().get(z);
20646                                                                        if (getColumnName(refer.getName()).equals(getColumnName(columnName))) {
20647                                                                                table = tTable;
20648                                                                                break;
20649                                                                        }
20650                                                                        if (refer.hasStarLinkColumn()) {
20651                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
20652                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
20653                                                                                                table = tTable;
20654                                                                                                break;
20655                                                                                        }
20656                                                                                }
20657                                                                        }
20658                                                                }
20659                                                        } else if (model instanceof QueryTable) {
20660                                                                QueryTable tableModel = (QueryTable) model;
20661                                                                for (int z = 0; tableModel.getColumns() != null
20662                                                                                && z < tableModel.getColumns().size(); z++) {
20663                                                                        ResultColumn refer = tableModel.getColumns().get(z);
20664                                                                        List<String> splits = SQLUtil.parseNames(columnName.toString());
20665                                                                        if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
20666                                                                                if (DlineageUtil.getIdentifierNormalColumnName(refer.getName())
20667                                                                                                .equals(DlineageUtil
20668                                                                                                                .getIdentifierNormalColumnName(getColumnName(splits.get(0))))) {
20669                                                                                        table = tTable;
20670                                                                                        break;
20671                                                                                }
20672                                                                        }
20673                                                                        else if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals(
20674                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
20675                                                                                table = tTable;
20676                                                                                break;
20677                                                                        }
20678                                                                        if (refer.hasStarLinkColumn()) {
20679                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
20680                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
20681                                                                                                table = tTable;
20682                                                                                                break;
20683                                                                                        }
20684                                                                                }
20685                                                                        }
20686                                                                }
20687                                                        }
20688                                                }
20689                                        }
20690                                }
20691
20692                                if (columnName.getTableToken() == null && "*".equals(getColumnName(columnName))) {
20693                                        if (!hasJoin(stmt)) {
20694                                                tables.add(table);
20695                                        } else {
20696                                                for (int j = 0; j < tableList.size(); j++) {
20697                                                        tables.add(tableList.getTable(j));
20698                                                }
20699                                        }
20700                                } else if (table != null) {
20701                                        tables.add(table);
20702                                }
20703
20704                                // 此处特殊处理,多表关联无法找到 column 所属的 Table, tTable.getLinkedColumns
20705                                // 也找不到,退而求其次采用第一个表
20706
20707                                if (stmt.getParentStmt() != null && isApplyJoin(stmt.getParentStmt())
20708                                                && (tableList != null && tableList.size() > 0)) {
20709                                        stmt = stmt.getParentStmt();
20710                                        TTable applyTable = tableList.getTable(0);
20711                                        if (modelManager.getModel(table) == null) {
20712                                                modelFactory.createTable(applyTable);
20713                                        }
20714                                }
20715
20716                                if (columnName.toString().indexOf(".")==-1 && isConstant(columnName)) {
20717                                        boolean isConstant = true;
20718                                        if (columnName.getSourceTable() != null) {
20719                                                Table tableModel = modelManager.getTableByName(
20720                                                                DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString()));
20721                                                if (tableModel != null && tableModel.getColumns() != null) {
20722                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
20723                                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
20724                                                                                getColumnName(tableModel.getColumns().get(j).getName()))) {
20725                                                                        isConstant = false;
20726                                                                        break;
20727                                                                }
20728                                                        }
20729                                                }
20730                                        }
20731
20732                                        if (isConstant) {
20733                                                if (option.isShowConstantTable()) {
20734                                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
20735                                                        TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false);
20736                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20737                                                }
20738                                                continue;
20739                                        }
20740                                }
20741
20742                                if (tableList != null && tableList.size() != 0 && tables.size() == 0
20743                                                && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) {
20744                                        if (modelManager.getModel(stmt) instanceof ResultSet) {
20745                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt);
20746                                                boolean find = false;
20747                                                for (ResultColumn resultColumn : resultSetModel.getColumns()) {
20748                                                        if(resultColumn.equals(modelObject)) {
20749                                                                continue;
20750                                                        }
20751                                                        if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) {
20752                                                                if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) {
20753                                                                        if (resultColumn.getColumnObject() != null) {
20754                                                                                int startToken = resultColumn.getColumnObject().getStartToken().posinlist;
20755                                                                                int endToken = resultColumn.getColumnObject().getEndToken().posinlist;
20756                                                                                if (columnName.getStartToken().posinlist >= startToken
20757                                                                                                && columnName.getEndToken().posinlist <= endToken) {
20758                                                                                        continue;
20759                                                                                }
20760                                                                        }
20761                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
20762                                                                        find = true;
20763                                                                        break;
20764                                                                }
20765                                                        }
20766                                                }
20767                                                if (find) {
20768                                                        continue;
20769                                                }
20770                                        }
20771                                        
20772                                        TObjectName pseudoTableName = new TObjectName();
20773                                        // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl)
20774                                        // Otherwise fall back to default pseudo table name
20775                                        String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName);
20776                                        pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column");
20777                                        Table pseudoTable = modelFactory.createTableByName(pseudoTableName);
20778                                        pseudoTable.setPseudo(true);
20779                                        TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true);
20780
20781                                        // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col),
20782                                        // add the pseudo table column as source
20783                                        if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) {
20784                                                if (isOut) {
20785                                                        relation.setTarget(new TableColumnRelationshipElement(pseudoTableColumn));
20786                                                } else {
20787                                                        relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn));
20788                                                }
20789                                        }
20790
20791                                        if (isLinkOrphanColumnToFirstTable()) {
20792                                                TTable orphanTable = tableList.getTable(0);
20793                                                tables.add(orphanTable);
20794                                                Object tableModel = modelManager.getModel(orphanTable);
20795                                                if (tableModel == null) {
20796                                                        if(orphanTable.getSubquery()!=null) {
20797                                                                QueryTable queryTable = modelFactory.createQueryTable(orphanTable);
20798                                                                TSelectSqlStatement subquery = orphanTable.getSubquery();
20799                                                                analyzeSelectStmt(subquery);
20800                                                        }
20801                                                        else {
20802                                                                tableModel = modelFactory.createTable(orphanTable);
20803                                                        }
20804                                                }
20805                                                if (tableModel instanceof Table) {
20806                                                        TableColumn orphanColum = modelFactory.createTableColumn((Table) tableModel, columnName, false);
20807                                                        if(orphanColum!=null) {
20808                                                                ErrorInfo errorInfo = new ErrorInfo();
20809                                                                errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN);
20810                                                                errorInfo.setErrorMessage("Link orphan column [" + columnName.toString()
20811                                                                                + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]");
20812                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo,
20813                                                                                columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
20814                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo,
20815                                                                                columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(),
20816                                                                                ModelBindingManager.getGlobalHash()));
20817                                                                errorInfo.fillInfo(this);
20818                                                                errorInfos.add(errorInfo);
20819                                                        }
20820                                                        if (orphanTable.getSubquery() != null) {
20821                                                                TSelectSqlStatement subquery = orphanTable.getSubquery();
20822                                                                if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) {
20823                                                                        TTable subqueryTable = subquery.getTables().getTable(0);
20824                                                                        Object sourceTable = modelManager.getModel(subqueryTable);
20825                                                                        if(sourceTable instanceof Table) {
20826                                                                                modelFactory.createTableColumn((Table) sourceTable, columnName, false);
20827                                                                        }
20828                                                                        else if(sourceTable instanceof ResultSet) {
20829                                                                                modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false);
20830                                                                        }
20831                                                                }
20832                                                        }
20833                                                        else if (orphanTable.getCTE()!=null && orphanTable.getCTE().getSubquery() != null) {
20834                                                                TSelectSqlStatement subquery = orphanTable.getCTE().getSubquery();
20835                                                                if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) {
20836                                                                        TTable subqueryTable = subquery.getTables().getTable(0);
20837                                                                        Object sourceTable = modelManager.getModel(subqueryTable);
20838                                                                        if(sourceTable instanceof Table) {
20839                                                                                modelFactory.createTableColumn((Table) sourceTable, columnName, false);
20840                                                                        }
20841                                                                        else if(sourceTable instanceof ResultSet) {
20842                                                                                modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false);
20843                                                                        }
20844                                                                }
20845                                                        }
20846                                                }
20847                                                
20848                                                linkedFirstTable = true;
20849                                        }
20850                                }
20851                        }
20852
20853                        for (int k = 0; k < tables.size(); k++) {
20854                                TTable table = tables.get(k);
20855                                if (table != null) {
20856                                        Object object = modelManager.getModel(table);
20857                                        if(object instanceof PivotedTable) {
20858                                                TPivotClause clause = (TPivotClause)((PivotedTable)object).getGspObject();
20859                                                if(clause.getAliasClause()!=null) {
20860                                                        object = modelManager.getModel(clause.getAliasClause());
20861                                                }
20862                                        }
20863                                        if (object == null && table.getTableType() == ETableSource.objectname) {
20864                                                if (table.getCTE() != null) {
20865                                                        QueryTable queryTable = modelFactory.createQueryTable(table);
20866                                                        TSelectSqlStatement subquery = table.getCTE().getSubquery();
20867                                                        analyzeSelectStmt(subquery);
20868                                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
20869
20870                                                        if (resultSetModel != null && resultSetModel != queryTable
20871                                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
20872                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
20873                                                                impactRelation.setEffectType(EffectType.select);
20874                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
20875                                                                                resultSetModel.getRelationRows()));
20876                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
20877                                                                                queryTable.getRelationRows()));
20878                                                        }
20879
20880                                                        if (resultSetModel != null && resultSetModel != queryTable) {
20881                                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
20882                                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
20883                                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
20884                                                                                        sourceColumn);
20885
20886                                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
20887                                                                        queryRalation.setEffectType(EffectType.select);
20888                                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
20889                                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
20890                                                                }
20891                                                        }
20892                                                        
20893                                                        object = queryTable;
20894                                                        
20895                                                } else {
20896                                                        object = modelFactory.createTable(table);
20897                                                }
20898                                        }
20899                                        if (object instanceof Function) {
20900                                                relation.addSource(new ResultColumnRelationshipElement(((Function)object).getColumns().get(0)));
20901                                                continue;
20902                                        } else if (object instanceof ResultSet && !(object instanceof QueryTable)) {
20903                                                //Object tableModel = modelManager.getModel(columnName.getSourceTable());
20904                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
20905                                                                (ResultSet)object);
20906                                                if(table.getTableType() == ETableSource.function && !relation.getSources().isEmpty()) {
20907                                                        relation.getSources().stream().reduce((first, second) -> second).get().addTransform(Transform.FUNCTION, table);
20908                                                }
20909                                                continue;
20910                                        }
20911                                        else if (object instanceof Table) {
20912                                                Table tableModel = (Table) modelManager.getModel(table);
20913                                                if (tableModel != null) {
20914                                                        if (!isStar && "*".equals(getColumnName(columnName))) {
20915                                                                TObjectName[] columns = modelManager.getTableColumns(table);
20916                                                                for (int j = 0; j < columns.length; j++) {
20917                                                                        TObjectName objectName = columns[j];
20918                                                                        if (objectName == null || ("*".equals(getColumnName(objectName)) && tableModel.isDetermined())) {
20919                                                                                continue;
20920                                                                        }
20921                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName,
20922                                                                                        false);
20923                                                                        if(columnModel == null) {
20924                                                                                continue;
20925                                                                        }
20926                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20927                                                                }
20928                                                        } else {
20929                                                                if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) {
20930                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
20931                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
20932                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
20933                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
20934                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
20935                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
20936                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
20937                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
20938                                                                                        }
20939                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20940                                                                                        if(tableModel.isDetermined()) {
20941                                                                                                resultSet.getColumns().clear();
20942                                                                                        }
20943                                                                                }
20944                                                                        }
20945                                                                        
20946                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
20947                                                                                TableColumn columnModel = tableModel.getColumns().get(j);
20948                                                                                if (exceptColumnList != null) {
20949                                                                                        boolean flag = false;
20950                                                                                        for (TObjectName objectName : exceptColumnList) {
20951                                                                                                if (getColumnName(objectName)
20952                                                                                                                .equals(getColumnName(columnModel.getColumnObject()))) {
20953                                                                                                        flag = true;
20954                                                                                                        break;
20955                                                                                                }
20956                                                                                        }
20957                                                                                        if (flag) {
20958                                                                                                continue;
20959                                                                                        }
20960                                                                                }
20961                                                                                
20962                                                                                if (replaceAsIdentifierMap.containsKey(tableModel.getColumns().get(j).getName())) {
20963                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableModel.getColumns().get(j).getName());
20964                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20965                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(tableModel.getColumns().get(j).getName()));
20966                                                                                        Transform transform = new Transform();
20967                                                                                        transform.setType(Transform.EXPRESSION);
20968                                                                                        TObjectName expression = new TObjectName();
20969                                                                                        expression.setString(expr.first);
20970                                                                                transform.setCode(expression);
20971                                                                                        resultColumn.setTransform(transform);
20972                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
20973                                                                                } else {
20974                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
20975                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
20976                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
20977                                                                                                                columnModel.getColumnObject());
20978                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
20979                                                                                                relation1.setEffectType(effectType);
20980                                                                                                relation1.setProcess(process);
20981                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
20982                                                                                                relation1.addSource(new TableColumnRelationshipElement(columnModel));
20983                                                                                        }
20984                                                                                        else {
20985                                                                                                relation.addSource(
20986                                                                                                        new TableColumnRelationshipElement(columnModel));
20987                                                                                        }
20988                                                                                }
20989                                                                        }
20990
20991                                                                        if (isStar && showStar) {
20992                                                                                TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
20993                                                                                                false);
20994                                                                                if (columnModel == null) {
20995                                                                                        if(tableModel.isCreateTable()) {
20996                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
20997                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20998                                                                                                        relation.setShowStarRelation(true);
20999                                                                                                }
21000                                                                                        }
21001                                                                                } else {
21002                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
21003                                                                                        relation.setShowStarRelation(true);
21004                                                                                }
21005                                                                        }
21006                                                                } else {
21007                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
21008                                                                                        false);
21009                                                                        if(columnModel == null) {
21010                                                                                if(tableModel.isCreateTable()) {
21011                                                                                        boolean flag = false;
21012                                                                                        if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvbigquery || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvredshift) {
21013                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
21014                                                                                                        if(tableColumn.isStruct()) {
21015                                                                                                                List<String> names = SQLUtil.parseNames(tableColumn.getName());
21016                                                                                                                if (modelObject instanceof TableColumn) {
21017                                                                                                                        TableColumn targetColumn = (TableColumn) modelObject;
21018                                                                                                                        if (targetColumn.isStruct()) {
21019                                                                                                                                List<String> targetNames = SQLUtil
21020                                                                                                                                                .parseNames(targetColumn.getName());
21021                                                                                                                                if (!getColumnName(targetNames.get(0))
21022                                                                                                                                                .equals(getColumnName(names.get(0)))) {
21023                                                                                                                                        continue;
21024                                                                                                                                }
21025                                                                                                                        }
21026                                                                                                                }
21027                                                                                                                else if (modelObject instanceof ResultColumn) {
21028                                                                                                                        ResultColumn targetColumn = (ResultColumn) modelObject;
21029                                                                                                                        if (targetColumn.isStruct()) {
21030                                                                                                                                List<String> targetNames = SQLUtil
21031                                                                                                                                                .parseNames(targetColumn.getName());
21032                                                                                                                                if (!getColumnName(targetNames.get(0))
21033                                                                                                                                                .equals(getColumnName(names.get(0)))) {
21034                                                                                                                                        continue;
21035                                                                                                                                }
21036                                                                                                                        }
21037                                                                                                                }
21038                                                                                                                for(String name: names) {
21039                                                                                                                        if (getColumnName(name)
21040                                                                                                                                        .equals(getColumnName(modelObject.toString()))) {
21041                                                                                                                                relation.addSource(
21042                                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21043                                                                                                                                flag = true;
21044                                                                                                                                if (modelObject instanceof ResultColumn) {
21045                                                                                                                                        ((ResultColumn)modelObject).setStruct(true);
21046                                                                                                                                }
21047                                                                                                                                else if (modelObject instanceof TableColumn) {
21048                                                                                                                                        ((TableColumn)modelObject).setStruct(true);
21049                                                                                                                                }
21050                                                                                                                                break;
21051                                                                                                                        }
21052                                                                                                                }
21053                                                                                                        }
21054                                                                                                        else if (getColumnName(tableColumn.getName())
21055                                                                                                                        .equals(getColumnName(modelObject.toString()))) {
21056                                                                                                                relation.addSource(
21057                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21058                                                                                                                flag = true;
21059                                                                                                                break;
21060                                                                                                        }
21061                                                                                                }
21062                                                                                                if (modelObject instanceof TableColumn) {
21063                                                                                                        TableColumn column = (TableColumn) modelObject;
21064                                                                                                        for (TableColumn tableColumn : tableModel.getColumns()) {
21065                                                                                                                if (tableColumn.getColumnIndex() == null) {
21066                                                                                                                        continue;
21067                                                                                                                }
21068                                                                                                                if (tableColumn.getName().toLowerCase()
21069                                                                                                                                .indexOf(column.getName().toLowerCase()) == -1
21070                                                                                                                                && tableColumn.getName().toLowerCase()
21071                                                                                                                                                .indexOf(column.getColumnObject().toString()
21072                                                                                                                                                                .toLowerCase()) == -1) {
21073                                                                                                                        continue;
21074                                                                                                                }
21075                                                                                                                flag = true;
21076                                                                                                                relation.addSource(
21077                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21078                                                                                                                relation.setShowStarRelation(true);
21079                                                                                                        }
21080                                                                                                        if (flag)
21081                                                                                                                break;
21082
21083                                                                                                } else if (modelObject instanceof ResultColumn) {
21084                                                                                                        ResultColumn column = (ResultColumn) modelObject;
21085                                                                                                        for (TableColumn tableColumn : tableModel.getColumns()) {
21086                                                                                                                if (tableColumn.getColumnIndex() == null) {
21087                                                                                                                        continue;
21088                                                                                                                }
21089                                                                                                                if (tableColumn.getName().toLowerCase()
21090                                                                                                                                .indexOf(column.getName().toLowerCase()) == -1
21091                                                                                                                                && tableColumn.getName().toLowerCase()
21092                                                                                                                                                .indexOf(column.getColumnObject().toString()
21093                                                                                                                                                                .toLowerCase()) == -1) {
21094                                                                                                                        continue;
21095                                                                                                                }
21096                                                                                                                flag = true;
21097                                                                                                                relation.addSource(
21098                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21099                                                                                                                relation.setShowStarRelation(true);
21100                                                                                                        }
21101                                                                                                        if (flag)
21102                                                                                                                break;
21103
21104                                                                                                }
21105                                                                                        }
21106                                                                                        if (!flag 
21107                                                                                                        && (isStar 
21108                                                                                                                        || getColumnName(columnName).equals(getColumnName(tableModel.getName()))
21109                                                                                                                        || getColumnName(columnName).equals(getColumnName(tableModel.getAlias())))) {
21110                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
21111                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
21112                                                                                                        relation.setShowStarRelation(true);
21113                                                                                                }
21114                                                                                        }
21115                                                                                }
21116                                                                        }
21117                                                                        else {
21118                                                                                if (linkedFirstTable) {
21119                                                                                        if (columnName.getCandidateTables() != null
21120                                                                                                        && columnName.getCandidateTables().size() > 1) {
21121                                                                                                List<Object> candidateParents = new ArrayList<Object>();
21122                                                                                                for(TTable tableItem: columnName.getCandidateTables()) {
21123                                                                                                        Object model = modelManager.getModel(tableItem);
21124                                                                                                        if(model!=null) {
21125                                                                                                                candidateParents.add(model);
21126                                                                                                        }
21127                                                                                                }
21128                                                                                                if (candidateParents.size() > 1) {
21129                                                                                                        columnModel.setCandidateParents(candidateParents);
21130                                                                                                }
21131                                                                                        }
21132                                                                                }
21133                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
21134                                                                                relation.setShowStarRelation(true);
21135                                                                                if (columnName.getSourceTable() != null
21136                                                                                                && columnName.getSourceTable().getTableType() == ETableSource.function) {
21137                                                                                        analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(),
21138                                                                                                        effectType);
21139                                                                                }
21140                                                                        }
21141                                                                }
21142                                                        }
21143                                                }
21144                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
21145                                                QueryTable queryTable = (QueryTable) modelManager.getModel(table);
21146
21147                                                TObjectNameList cteColumns = null;
21148                                                TSelectSqlStatement subquery = null;
21149                                                if (queryTable.getTableObject().getCTE() != null) {
21150                                                        subquery = queryTable.getTableObject().getCTE().getSubquery();
21151                                                        cteColumns = queryTable.getTableObject().getCTE().getColumnList();
21152                                                } else if (queryTable.getTableObject().getAliasClause() != null
21153                                                                && queryTable.getTableObject().getAliasClause().getColumns() != null) {
21154
21155                                                } else if (queryTable.getTableObject().getTableExpr() != null
21156                                                                && queryTable.getTableObject().getTableExpr().getSubQuery() != null) {
21157                                                        subquery = queryTable.getTableObject().getTableExpr().getSubQuery();
21158                                                } else {
21159                                                        subquery = queryTable.getTableObject().getSubquery();
21160                                                }
21161
21162                                                if (cteColumns != null) {
21163                                                        for (int j = 0; j < cteColumns.size(); j++) {
21164                                                                modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
21165                                                        }
21166                                                }
21167
21168                                                if (subquery != null && subquery.isCombinedQuery()) {
21169                                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
21170                                                                        .getModel(subquery);
21171
21172                                                        if (selectSetResultSetModel != null
21173                                                                        && !selectSetResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
21174                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
21175                                                                impactRelation.setEffectType(EffectType.select);
21176                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21177                                                                                selectSetResultSetModel.getRelationRows()));
21178                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21179                                                                                queryTable.getRelationRows()));
21180                                                        }
21181
21182                                                        if (selectSetResultSetModel != null) {
21183                                                                if (getColumnName(columnName).equals("*")) {
21184                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
21185                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
21186                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
21187                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
21188                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
21189                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
21190                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
21191                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
21192                                                                                        }
21193                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21194                                                                                        if(selectSetResultSetModel.isDetermined()) {
21195                                                                                                resultSet.getColumns().clear();
21196                                                                                        }
21197                                                                                }
21198                                                                        }
21199                                                                        
21200                                                                        
21201                                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
21202                                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
21203                                                                                if (cteColumns != null) {
21204                                                                                        if (j < cteColumns.size()) {
21205                                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
21206
21207                                                                                                if (exceptColumnList != null) {
21208                                                                                                        boolean flag = false;
21209                                                                                                        for (TObjectName objectName : exceptColumnList) {
21210                                                                                                                if (getColumnName(objectName)
21211                                                                                                                                .equals(getColumnName(targetColumn.getName()))) {
21212                                                                                                                        flag = true;
21213                                                                                                                        break;
21214                                                                                                                }
21215                                                                                                        }
21216                                                                                                        if (flag) {
21217                                                                                                                continue;
21218                                                                                                        }
21219                                                                                                }
21220
21221                                                                                                if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
21222                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
21223                                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21224                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
21225                                                                                                        Transform transform = new Transform();
21226                                                                                                        transform.setType(Transform.EXPRESSION);
21227                                                                                                        TObjectName expression = new TObjectName();
21228                                                                                                        expression.setString(expr.first);
21229                                                                                                transform.setCode(expression);
21230                                                                                                        resultColumn.setTransform(transform);
21231                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
21232                                                                                                } else {
21233                                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
21234                                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
21235                                                                                                                TObjectName resultColumnName = new TObjectName();
21236                                                                                                                resultColumnName.setString(targetColumn.getName());
21237                                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
21238                                                                                                                                resultColumnName);
21239                                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
21240                                                                                                                relation1.setEffectType(effectType);
21241                                                                                                                relation1.setProcess(process);
21242                                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
21243                                                                                                                relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
21244                                                                                                        }
21245                                                                                                        else {
21246                                                                                                                relation.addSource(
21247                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21248                                                                                                        }
21249                                                                                                }
21250                                                                                                
21251                                                                                        }
21252                                                                                } else {
21253                                                                                        ResultColumn targetColumn = modelFactory
21254                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21255
21256                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21257                                                                                                        .createDataFlowRelation();
21258                                                                                        combinedQueryRelation.setEffectType(effectType);
21259                                                                                        combinedQueryRelation
21260                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
21261                                                                                        combinedQueryRelation
21262                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
21263
21264                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21265                                                                                }
21266                                                                        }
21267                                                                        break;
21268                                                                } else {
21269                                                                        boolean flag = false;
21270
21271                                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
21272                                                                                ResultColumn sourceColumn = selectSetResultSetModel
21273                                                                                                .getColumns().get(j);
21274                                                                                List<String> splits = SQLUtil.parseNames(columnName.toString());        
21275                                                                                if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
21276                                                                                        if (getColumnName(sourceColumn.getName())
21277                                                                                                        .equalsIgnoreCase(getColumnName(splits.get(0)))
21278                                                                                                        || getColumnName(sourceColumn.getName())
21279                                                                                                                        .equalsIgnoreCase(getColumnName(splits.get(1)))) {
21280                                                                                                ResultColumn targetColumn = modelFactory
21281                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
21282
21283                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
21284                                                                                                                .createDataFlowRelation();
21285                                                                                                combinedQueryRelation.setEffectType(effectType);
21286                                                                                                combinedQueryRelation.setTarget(
21287                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21288                                                                                                combinedQueryRelation.addSource(
21289                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
21290
21291                                                                                                relation.addSource(
21292                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21293                                                                                                flag = true;
21294                                                                                                break;
21295                                                                                        }
21296                                                                                }
21297                                                                                else if (getColumnName(sourceColumn.getName())
21298                                                                                                .equalsIgnoreCase(getColumnName(columnName))) {
21299                                                                                        ResultColumn targetColumn = modelFactory
21300                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21301
21302                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21303                                                                                                        .createDataFlowRelation();
21304                                                                                        combinedQueryRelation.setEffectType(effectType);
21305                                                                                        combinedQueryRelation
21306                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
21307                                                                                        combinedQueryRelation
21308                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
21309
21310                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21311                                                                                        flag = true;
21312                                                                                        break;
21313                                                                                }
21314                                                                                else if (sourceColumn instanceof SelectSetResultColumn && ((SelectSetResultColumn)sourceColumn).getAliasSet().size() > 1) {
21315                                                                                        for (String alias : ((SelectSetResultColumn)sourceColumn).getAliasSet()) {
21316                                                                                                if (getColumnName(alias).equalsIgnoreCase(getColumnName(columnName))) {
21317                                                                                                        ResultColumn targetColumn = modelFactory
21318                                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21319
21320                                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21321                                                                                                                        .createDataFlowRelation();
21322                                                                                                        combinedQueryRelation.setEffectType(effectType);
21323                                                                                                        combinedQueryRelation.setTarget(
21324                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21325                                                                                                        combinedQueryRelation.addSource(
21326                                                                                                                        new ResultColumnRelationshipElement(sourceColumn));
21327
21328                                                                                                        relation.addSource(
21329                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21330                                                                                                        flag = true;
21331                                                                                                        break;
21332                                                                                                }
21333                                                                                        }
21334                                                                                        if (flag) {
21335                                                                                                break;
21336                                                                                        }
21337                                                                                }
21338                                                                        }
21339
21340                                                                        if (flag) {
21341                                                                                break;
21342                                                                        } else if (columnIndex != -1) {
21343                                                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
21344                                                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
21345                                                                                        if (!sourceColumn.getStarLinkColumns().isEmpty()) {
21346                                                                                                if (cteColumns != null) {
21347                                                                                                        if (j < cteColumns.size()) {
21348                                                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
21349                                                                                                                relation.addSource(
21350                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21351                                                                                                        }
21352                                                                                                } 
21353                                                                                                else {
21354                                                                                                        if(sourceColumn.hasStarLinkColumn()) {
21355                                                                                                                for (TObjectName linkColumn : sourceColumn.getStarLinkColumnList()) {
21356                                                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
21357                                                                                                                                ResultColumn targetColumn = modelFactory
21358                                                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
21359
21360                                                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
21361                                                                                                                                                .createDataFlowRelation();
21362                                                                                                                                combinedQueryRelation.setEffectType(effectType);
21363                                                                                                                                combinedQueryRelation.setTarget(
21364                                                                                                                                                new ResultColumnRelationshipElement(targetColumn, linkColumn));
21365                                                                                                                                combinedQueryRelation.addSource(
21366                                                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
21367
21368                                                                                                                                relation.addSource(
21369                                                                                                                                                new ResultColumnRelationshipElement(targetColumn, linkColumn));
21370                                                                                                                                flag = true;
21371                                                                                                                                break;
21372                                                                                                                        }
21373                                                                                                                }
21374                                                                                                        }
21375                                                                                                        
21376                                                                                                        if(!flag) {
21377                                                                                                                ResultColumn targetColumn = modelFactory
21378                                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
21379
21380                                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
21381                                                                                                                                .createDataFlowRelation();
21382                                                                                                                combinedQueryRelation.setEffectType(effectType);
21383                                                                                                                combinedQueryRelation.setTarget(
21384                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21385                                                                                                                combinedQueryRelation.addSource(
21386                                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
21387
21388                                                                                                                relation.addSource(
21389                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21390                                                                                                        }
21391                                                                                                }
21392                                                                                                flag = true;
21393                                                                                                break;
21394                                                                                        }
21395                                                                                }
21396                                                                        }
21397
21398                                                                        if (flag) {
21399                                                                                break;
21400                                                                        } else if (columnIndex < selectSetResultSetModel.getColumns().size()
21401                                                                                        && columnIndex != -1) {
21402                                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns()
21403                                                                                                .get(columnIndex);
21404                                                                                if (cteColumns != null) {
21405                                                                                        boolean flag1 = false;
21406                                                                                        for (ResultColumn targetColumn : queryTable.getColumns()) {
21407                                                                                                if (getColumnName(targetColumn.getName())
21408                                                                                                                .equalsIgnoreCase(getColumnName(columnName))) {
21409                                                                                                        relation.addSource(
21410                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21411                                                                                                        flag1 = true;
21412                                                                                                        break;
21413                                                                                                }
21414                                                                                        }
21415                                                                                        if (!flag1 && columnIndex < cteColumns.size()){
21416                                                                                                ResultColumn targetColumn = queryTable.getColumns()
21417                                                                                                                .get(columnIndex);
21418                                                                                                relation.addSource(
21419                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21420                                                                                        }
21421                                                                                } else {
21422                                                                                        ResultColumn targetColumn = modelFactory
21423                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21424
21425                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21426                                                                                                        .createDataFlowRelation();
21427                                                                                        combinedQueryRelation.setEffectType(effectType);
21428                                                                                        combinedQueryRelation
21429                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
21430                                                                                        combinedQueryRelation
21431                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
21432
21433                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21434                                                                                }
21435                                                                                flag = true;
21436                                                                                break;
21437                                                                        }
21438
21439                                                                        if (flag) {
21440                                                                                break;
21441                                                                        }
21442                                                                }
21443                                                        } else if (cteColumns != null) {
21444                                                                if (getColumnName(columnName).equals("*")) {
21445                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
21446                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
21447                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
21448                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
21449                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
21450                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
21451                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
21452                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
21453                                                                                        }
21454                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21455                                                                                        
21456                                                                                        if (columnName.getSourceColumn() != null) {
21457                                                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
21458                                                                                                if (model instanceof ResultColumn && ((ResultColumn)model).getResultSet().isDetermined()) {
21459                                                                                                        resultSet.getColumns().clear();
21460                                                                                                }
21461                                                                                        } else if (columnName.getSourceTable() != null) {
21462                                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
21463                                                                                                if (tableModel instanceof Table && ((Table)tableModel).isDetermined()) {
21464                                                                                                        resultSet.getColumns().clear();
21465                                                                                                }
21466                                                                                        }
21467                                                                                }
21468                                                                        }
21469                                                                        
21470                                                                        for (int j = 0; j < cteColumns.size(); j++) {
21471                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
21472
21473                                                                                if (exceptColumnList != null) {
21474                                                                                        boolean flag = false;
21475                                                                                        for (TObjectName objectName : exceptColumnList) {
21476                                                                                                if (getColumnName(objectName)
21477                                                                                                                .equals(getColumnName(targetColumn.getName()))) {
21478                                                                                                        flag = true;
21479                                                                                                        break;
21480                                                                                                }
21481                                                                                        }
21482                                                                                        if (flag) {
21483                                                                                                continue;
21484                                                                                        }
21485                                                                                }
21486
21487                                                                                if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
21488                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
21489                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21490                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
21491                                                                                        Transform transform = new Transform();
21492                                                                                        transform.setType(Transform.EXPRESSION);
21493                                                                                        TObjectName expression = new TObjectName();
21494                                                                                        expression.setString(expr.first);
21495                                                                                transform.setCode(expression);
21496                                                                                        resultColumn.setTransform(transform);
21497                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
21498                                                                                } else {
21499                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
21500                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
21501                                                                                                TObjectName resultColumnName = new TObjectName();
21502                                                                                                resultColumnName.setString(targetColumn.getName());
21503                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
21504                                                                                                                resultColumnName);
21505                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
21506                                                                                                relation1.setEffectType(effectType);
21507                                                                                                relation1.setProcess(process);
21508                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
21509                                                                                                relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
21510                                                                                        }
21511                                                                                        else {
21512                                                                                                relation.addSource(
21513                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21514                                                                                        }
21515                                                                                }
21516                                                                        }
21517                                                                        break;
21518                                                                } else {
21519                                                                        boolean flag = false;
21520
21521                                                                        for (int j = 0; j < cteColumns.size(); j++) {
21522                                                                                TObjectName sourceColumn = cteColumns.getObjectName(j);
21523
21524                                                                                if (getColumnName(sourceColumn).equalsIgnoreCase(getColumnName(columnName))) {
21525                                                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
21526
21527                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21528                                                                                        flag = true;
21529                                                                                        break;
21530                                                                                }
21531                                                                        }
21532
21533                                                                        if (flag) {
21534                                                                                break;
21535                                                                        }
21536                                                                }
21537                                                        }
21538
21539                                                        if (columnName.getSourceColumn() != null) {
21540                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
21541                                                                if (model instanceof ResultColumn) {
21542                                                                        ResultColumn resultColumn = (ResultColumn) model;
21543                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
21544                                                                }
21545                                                        } else if (columnName.getSourceTable() != null) {
21546                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
21547                                                                if (tableModel instanceof Table) {
21548                                                                        Object model = modelManager
21549                                                                                        .getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName));
21550                                                                        if (model instanceof TableColumn) {
21551                                                                                relation.addSource(new TableColumnRelationshipElement((TableColumn) model));
21552                                                                        }
21553                                                                }
21554                                                        }
21555                                                } else {
21556                                                        List<ResultColumn> columns = queryTable.getColumns();
21557                                                        if (getColumnName(columnName).equals("*")) {
21558                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
21559                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
21560                                                                if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
21561                                                                        TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
21562                                                                        if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
21563                                                                                for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
21564                                                                                        replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
21565                                                                                        replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
21566                                                                                }
21567                                                                                ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21568                                                                                if(queryTable.isDetermined()) {
21569                                                                                        resultSet.getColumns().clear();
21570                                                                                }
21571                                                                        }
21572                                                                }
21573                                                                
21574                                                                int index = 0;
21575                                                                for (int j = 0; j < queryTable.getColumns().size(); j++) {
21576                                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
21577                                                                        if (exceptColumnList != null) {
21578                                                                                boolean flag = false;
21579                                                                                for (TObjectName objectName : exceptColumnList) {
21580                                                                                        if (getColumnName(objectName)
21581                                                                                                        .equals(getColumnName(targetColumn.getName()))) {
21582                                                                                                flag = true;
21583                                                                                                break;
21584                                                                                        }
21585                                                                                }
21586                                                                                if (flag) {
21587                                                                                        continue;
21588                                                                                }
21589                                                                        }
21590                                                                        
21591                                                                        if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
21592                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
21593                                                                                ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21594                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
21595                                                                                Transform transform = new Transform();
21596                                                                                transform.setType(Transform.EXPRESSION);
21597                                                                                TObjectName expression = new TObjectName();
21598                                                                                expression.setString(expr.first);
21599                                                                        transform.setCode(expression);
21600                                                                                resultColumn.setTransform(transform);
21601                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
21602                                                                        } else {
21603                                                                                if(!replaceAsIdentifierMap.isEmpty()) {
21604                                                                                        ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
21605                                                                                        TObjectName resultColumnName = new TObjectName();
21606                                                                                        resultColumnName.setString(targetColumn.getName());
21607                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
21608                                                                                                        resultColumnName);
21609                                                                                        DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
21610                                                                                        relation1.setEffectType(effectType);
21611                                                                                        relation1.setProcess(process);
21612                                                                                        relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
21613                                                                                        relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
21614                                                                                }
21615                                                                                else {
21616                                                                                        relation.addSource(
21617                                                                                                new ResultColumnRelationshipElement(targetColumn));
21618                                                                                }
21619                                                                        }
21620                                                                        index++;
21621                                                                }
21622                                                        } else {
21623                                                                if (table.getCTE() != null) {
21624                                                                        
21625                                                                        if (modelObject instanceof TableColumn) {
21626                                                                                Table modelTable = ((TableColumn) modelObject).getTable();
21627                                                                                if (modelTable.getSubType() == SubType.unnest) {
21628                                                                                        boolean find = false;
21629                                                                                        for (k = 0; k < columns.size(); k++) {
21630                                                                                                ResultColumn column = columns.get(k);
21631                                                                                                if (column.isStruct()) {
21632                                                                                                        List<String> names = SQLUtil.parseNames(column.getName());
21633                                                                                                        for (String name : names) {
21634                                                                                                                if (getColumnName(name).equals(getColumnName(columnName))) {
21635                                                                                                                        DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation();
21636                                                                                                                        unnestRelation.setEffectType(effectType);
21637                                                                                                                        unnestRelation.setProcess(process);
21638                                                                                                                        unnestRelation.addSource(new ResultColumnRelationshipElement(
21639                                                                                                                                        column, columnName));
21640                                                                                                                        TObjectName unnestTableColumnName = new TObjectName();
21641                                                                                                                        unnestTableColumnName.setString(names.get(names.size()-1));
21642                                                                                                                        TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true);
21643                                                                                                                        unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
21644                                                                                                                        find = true;
21645                                                                                                                }
21646                                                                                                        }
21647                                                                                                        List<String> names1 = SQLUtil.parseNames(column.getName());
21648                                                                                                        if (names.size() == 1 && names1.size() >= 1) {
21649                                                                                                                for (String name : names1) {
21650                                                                                                                        if (getColumnName(name)
21651                                                                                                                                        .equals(getColumnName(column.getName()))) {
21652                                                                                                                                DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation();
21653                                                                                                                                unnestRelation.setEffectType(effectType);
21654                                                                                                                                unnestRelation.setProcess(process);
21655                                                                                                                                unnestRelation.addSource(new ResultColumnRelationshipElement(
21656                                                                                                                                                column, columnName));
21657                                                                                                                                TObjectName unnestTableColumnName = new TObjectName();
21658                                                                                                                                unnestTableColumnName.setString(names1.get(names.size()-1));
21659                                                                                                                                TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true);
21660                                                                                                                                unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
21661                                                                                                                                find = true;
21662                                                                                                                        }
21663                                                                                                                }
21664                                                                                                        }
21665                                                                                                }
21666                                                                                        }
21667                                                                                        if (find) {
21668                                                                                                modelTable.getColumns().remove(modelObject);
21669                                                                                                break;
21670                                                                                        }
21671                                                                                }
21672                                                                        }
21673                                                                        
21674                                                                        for (k = 0; k < columns.size(); k++) {
21675                                                                                ResultColumn column = columns.get(k);
21676                                                                                if ("*".equals(column.getName())) {
21677                                                                                        if (!containsStarColumn(column, columnName)) {
21678                                                                                                column.bindStarLinkColumn(columnName);
21679                                                                                        }
21680                                                                                        relation.addSource(new ResultColumnRelationshipElement(column, columnName));
21681                                                                                } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
21682                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
21683                                                                                        if (!column.equals(modelObject)) {
21684                                                                                                relation.addSource(
21685                                                                                                                new ResultColumnRelationshipElement(column, columnName));
21686                                                                                        }
21687                                                                                        break;
21688                                                                                } else if(column.isStruct()) {
21689                                                                                        List<String> names = SQLUtil.parseNames(column.getName());
21690                                                                                        for(String name: names) {
21691                                                                                                if (getColumnName(name)
21692                                                                                                                .equals(getColumnName(columnName))) {
21693                                                                                                        relation.addSource(
21694                                                                                                                        new ResultColumnRelationshipElement(column, columnName));
21695                                                                                                }
21696                                                                                        }
21697                                                                                        List<String> names1 = SQLUtil.parseNames(column.getName());
21698                                                                                        if (names.size() == 1 && names1.size() >= 1) {
21699                                                                                                for(String name: names1) {
21700                                                                                                        if (getColumnName(name)
21701                                                                                                                        .equals(getColumnName(column.getName()))) {
21702                                                                                                                relation.addSource(
21703                                                                                                                                new ResultColumnRelationshipElement(column, columnName));
21704                                                                                                        }
21705                                                                                                }
21706                                                                                        }
21707                                                                                }
21708                                                                        }
21709                                                                } else if (table.getAliasClause() != null
21710                                                                                && table.getAliasClause().getColumns() != null) {
21711                                                                        for (k = 0; k < columns.size(); k++) {
21712                                                                                ResultColumn column = columns.get(k);
21713                                                                                List<String> splits = SQLUtil.parseNames(columnName.toString());        
21714                                                                                if ("*".equals(column.getName())) {
21715                                                                                        if (!containsStarColumn(column, columnName)) {
21716                                                                                                column.bindStarLinkColumn(columnName);
21717                                                                                        }
21718                                                                                        relation.addSource(new ResultColumnRelationshipElement(column, columnName));
21719                                                                                } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
21720                                                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)),
21721                                                                                                        DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
21722                                                                                                if (!column.equals(modelObject)) {
21723                                                                                                        relation.addSource(new ResultColumnRelationshipElement(column,
21724                                                                                                                        columnName));
21725                                                                                                }
21726                                                                                                break;
21727                                                                                        }
21728                                                                                } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
21729                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
21730                                                                                        if (!column.equals(modelObject)) {
21731                                                                                                relation.addSource(
21732                                                                                                                new ResultColumnRelationshipElement(column, columnName));
21733                                                                                        }
21734                                                                                        break;
21735                                                                                }
21736                                                                        }
21737                                                                } else if (table.getSubquery() != null || (table.getTableExpr() != null
21738                                                                                && table.getTableExpr().getSubQuery() != null)) {
21739                                                                        TSelectSqlStatement select = table.getSubquery();
21740                                                                        if (select == null) {
21741                                                                                select = table.getTableExpr().getSubQuery();
21742                                                                        }
21743                                                                        if (columnName.getSourceTable() != null) {
21744                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
21745                                                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
21746                                                                                                tableModel);
21747                                                                        } else if (columnName.getObjectToken() != null
21748                                                                                        && !SQLUtil.isEmpty(table.getAliasName())) {
21749                                                                                if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(),
21750                                                                                                table.getAliasName())) {
21751                                                                                        Object tableModel = modelManager.getModel(table);
21752                                                                                        appendResultColumnRelationSource(modelObject, relation, columnIndex,
21753                                                                                                        columnName, tableModel);
21754                                                                                }
21755                                                                        } else if(columns!=null) {
21756                                                                                for (k = 0; k < columns.size(); k++) {
21757                                                                                        ResultColumn column = columns.get(k);
21758                                                                                        List<String> splits = SQLUtil.parseNames(columnName.toString());        
21759                                                                                        if ("*".equals(column.getName())) {
21760                                                                                                if (!containsStarColumn(column, columnName)) {
21761                                                                                                        column.bindStarLinkColumn(columnName);
21762                                                                                                }
21763                                                                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
21764                                                                                        } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
21765                                                                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)),
21766                                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
21767                                                                                                        if (!column.equals(modelObject)) {
21768                                                                                                                relation.addSource(new ResultColumnRelationshipElement(column,
21769                                                                                                                                columnName));
21770                                                                                                        }
21771                                                                                                        break;
21772                                                                                                }
21773                                                                                        } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
21774                                                                                                        DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
21775                                                                                                if (!column.equals(modelObject)) {
21776                                                                                                        relation.addSource(
21777                                                                                                                        new ResultColumnRelationshipElement(column, columnName));
21778                                                                                                }
21779                                                                                                break;
21780                                                                                        }
21781                                                                                }
21782                                                                        }
21783                                                                } else if (table.getOutputMerge() != null) {
21784                                                                        if (columnName.getSourceColumn() != null) {
21785                                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
21786                                                                                if (model instanceof ResultColumn) {
21787                                                                                        ResultColumn resultColumn = (ResultColumn) model;
21788                                                                                        if ("*".equals(resultColumn.getName())
21789                                                                                                        && !containsStarColumn(resultColumn, columnName)) {
21790                                                                                                resultColumn.bindStarLinkColumn(columnName);
21791                                                                                        }
21792                                                                                        relation.addSource(
21793                                                                                                        new ResultColumnRelationshipElement(resultColumn, columnName));
21794                                                                                }
21795                                                                        } else if (columnName.getSourceTable() != null) {
21796                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
21797                                                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
21798                                                                                                tableModel);
21799                                                                        } else if (columnName.getObjectToken() != null
21800                                                                                        && !SQLUtil.isEmpty(table.getAliasName())) {
21801                                                                                if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(),
21802                                                                                                table.getAliasName())) {
21803                                                                                        Object tableModel = modelManager.getModel(table);
21804                                                                                        appendResultColumnRelationSource(modelObject, relation, columnIndex,
21805                                                                                                        columnName, tableModel);
21806                                                                                }
21807                                                                        }
21808                                                                }
21809                                                        }
21810                                                }
21811                                        }
21812                                }
21813                        }
21814                        if (relation.getSources().size() == 0 && isKeyword(columnName)) {
21815                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
21816                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable, columnName, true);
21817                                relation.addSource(new ConstantRelationshipElement(constantColumn));
21818                        }
21819
21820                        if (relation.getSources().size() > 0) {
21821                                for (RelationshipElement<?> sourceItem: relation.getSources()) {
21822                                        Object source = sourceItem.getElement();
21823                                        ImpactRelationship impactRelation = null;
21824                                        if (source instanceof ResultColumn
21825                                                        && !((ResultColumn) source).getResultSet().getRelationRows().getHoldRelations().isEmpty()) {
21826                                                impactRelation = modelFactory.createImpactRelation();
21827                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21828                                                                ((ResultColumn) source).getResultSet().getRelationRows()));
21829                                                impactRelation.setEffectType(effectType);
21830                                        } else if (source instanceof TableColumn
21831                                                        && !((TableColumn) source).getTable().getRelationRows().getHoldRelations().isEmpty()) {
21832                                                impactRelation = modelFactory.createImpactRelation();
21833                                                impactRelation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(
21834                                                                ((TableColumn) source).getTable().getRelationRows()));
21835                                                impactRelation.setEffectType(effectType);;
21836                                        }
21837
21838                                        if (impactRelation == null) {
21839                                                continue;
21840                                        }
21841
21842                                        Object target = relation.getTarget().getElement();
21843                                        if (target instanceof ResultColumn) {
21844                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21845                                                                ((ResultColumn) target).getResultSet().getRelationRows()));
21846                                        } else if (target instanceof TableColumn) {
21847                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
21848                                                                ((TableColumn) target).getTable().getRelationRows()));
21849                                        }
21850
21851                                        if (impactRelation.getSources().iterator().next().getElement() == impactRelation.getTarget().getElement()) {
21852                                                modelManager.removeRelation(impactRelation);
21853                                        }
21854                                }
21855                        }
21856                }
21857                return relation;
21858        }
21859
21860        private boolean isNotInProcedure(Table table) {
21861        TStoredProcedureSqlStatement stmt = getProcedureParent(stmtStack.peek());
21862                Procedure procedure = this.modelFactory.createProcedure(stmt);
21863                if(procedure!=null && procedure.getName().equals(table.getParent())){
21864                        return false;
21865                }
21866                return true;
21867        }
21868
21869        private boolean hasJoin(TCustomSqlStatement stmt) {
21870                if (stmt.getJoins() == null || stmt.getJoins().size() == 0)
21871                        return false;
21872                if (stmt.getJoins().size() > 1) {
21873                        return true;
21874                }
21875                TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems();
21876                if (joinItems == null || joinItems.size() == 0) {
21877                        return false;
21878                }
21879                return true;
21880        }
21881
21882        private boolean isInQuery(TSelectSqlStatement query, TResultColumn column) {
21883                if(query == null)
21884                        return false;
21885                TResultColumnList columns = query.getResultColumnList();
21886                if (columns != null) {
21887                        for (int i = 0; i < columns.size(); i++) {
21888                                if (columns.getResultColumn(i).equals(column)) {
21889                                        return true;
21890                                }
21891                        }
21892                }
21893                return false;
21894        }
21895
21896        private void appendResultColumnRelationSource(Object modelObject, DataFlowRelationship relation, int columnIndex,
21897                        TObjectName columnName, Object tableModel) {
21898                if (tableModel instanceof Table) {
21899                        Object model = modelManager.getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName));
21900                        if (model instanceof TableColumn) {
21901                                relation.addSource(new TableColumnRelationshipElement((TableColumn) model));
21902                        }
21903                } else if (tableModel instanceof ResultSet) {
21904                        List<ResultColumn> queryColumns = ((ResultSet) tableModel).getColumns();
21905                        boolean flag = false;
21906                        for (int l = 0; l < queryColumns.size(); l++) {
21907                                ResultColumn column = queryColumns.get(l);
21908                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
21909                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
21910                                        if (!column.equals(modelObject)) {
21911                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
21912                                                flag = true;
21913                                        }
21914                                        break;
21915                                }
21916                        }
21917                        if (!flag) {
21918                                for (int l = 0; l < queryColumns.size(); l++) {
21919                                        ResultColumn column = queryColumns.get(l);
21920                                        if ("*".equals(column.getName())) {
21921                                                if (!containsStarColumn(column, columnName)) {
21922                                                        column.bindStarLinkColumn(columnName);
21923                                                }
21924                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
21925                                                flag = true;
21926                                                break;
21927                                        }
21928                                }
21929                        }
21930                        if (!flag && columnIndex < queryColumns.size() && columnIndex != -1) {
21931                                relation.addSource(new ResultColumnRelationshipElement(queryColumns.get(columnIndex), columnName));
21932                        }
21933                }
21934        }
21935
21936        private boolean isApplyJoin(TCustomSqlStatement stmt) {
21937                if (stmt.getJoins() == null || stmt.getJoins().size() == 0)
21938                        return false;
21939                TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems();
21940                if (joinItems == null || joinItems.size() == 0) {
21941                        return false;
21942                }
21943                if (joinItems.getJoinItem(0).getJoinType() == EJoinType.crossapply
21944                                || joinItems.getJoinItem(0).getJoinType() == EJoinType.outerapply)
21945                        return true;
21946                return false;
21947        }
21948
21949        private boolean containsStarColumn(ResultColumn resultColumn, TObjectName columnName) {
21950                String targetColumnName = getColumnName(columnName);
21951                if (resultColumn.hasStarLinkColumn()) {
21952                        return resultColumn.getStarLinkColumns().containsKey(targetColumnName);
21953                }
21954                return false;
21955        }
21956
21957        private void analyzeAggregate(TFunctionCall function, TExpression expr) {
21958                TCustomSqlStatement stmt = stmtStack.peek();
21959                ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
21960                if (resultSet == null) {
21961                        return;
21962                }
21963
21964                if (expr != null) {
21965                        columnsInExpr visitor = new columnsInExpr();
21966                        expr.inOrderTraverse(visitor);
21967                        List<TObjectName> objectNames = visitor.getObjectNames();
21968                        for (int j = 0; j < objectNames.size(); j++) {
21969                                TObjectName columnName = objectNames.get(j);
21970
21971                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
21972                                        continue;
21973                                }
21974
21975                                if (columnName.getColumnNameOnly().startsWith("@")
21976                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
21977                                        continue;
21978                                }
21979
21980                                if (columnName.getColumnNameOnly().startsWith(":")
21981                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
21982                                        continue;
21983                                }
21984
21985                                if(modelManager.getModel(function.getFunctionName()) == null) {
21986                                        continue;
21987                                }
21988                                AbstractRelationship relation = modelFactory.createRecordSetRelation();
21989                                relation.setEffectType(EffectType.function);
21990                                relation.setFunction(function.getFunctionName().toString());
21991                                relation.setTarget(new ResultColumnRelationshipElement(
21992                                                (ResultColumn) modelManager.getModel(function.getFunctionName())));
21993                                TTable table = modelManager.getTable(stmt, columnName);
21994                                if (table != null) {
21995                                        if (modelManager.getModel(table) instanceof Table) {
21996                                                Table tableModel = (Table) modelManager.getModel(table);
21997                                                if (tableModel != null) {
21998                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
21999                                                        if (columnModel != null) {
22000                                                                relation.addSource(
22001                                                                                new TableColumnRelationshipElement(columnModel, columnName.getLocation()));
22002                                                        }
22003                                                }
22004                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
22005                                                Object model = modelManager.getModel(columnName.getSourceColumn());
22006                                                if (model instanceof ResultColumn) {
22007                                                        ResultColumn resultColumn = (ResultColumn) model;
22008                                                        if (resultColumn != null) {
22009                                                                relation.addSource(
22010                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
22011                                                        }
22012                                                }
22013                                        }
22014                                }
22015                        }
22016
22017                        List<TParseTreeNode> functions = visitor.getFunctions();
22018                        for (int j = 0; j < functions.size(); j++) {
22019                                TParseTreeNode functionObj = functions.get(j);
22020                                Object functionModel = modelManager.getModel(functionObj);
22021                                if (functionModel == null) {
22022                                        functionModel = createFunction(functionObj);
22023                                }
22024                                if (functionModel instanceof Function) {
22025                                        AbstractRelationship relation;
22026                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22027                                                // relation = modelFactory.createDataFlowRelation();
22028                                                relation = modelFactory.createRecordSetRelation();
22029                                        } else {
22030                                                relation = modelFactory.createRecordSetRelation();
22031                                        }
22032                                        relation.setEffectType(EffectType.function);
22033                                        relation.setFunction(function.getFunctionName().toString());
22034                                        relation.setTarget(new ResultColumnRelationshipElement(
22035                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22036
22037                                        if (functionObj instanceof TFunctionCall) {
22038                                                ResultColumn resultColumn = (ResultColumn) modelManager
22039                                                                .getModel(((TFunctionCall) functionObj).getFunctionName());
22040                                                if (resultColumn != null) {
22041                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn,
22042                                                                        ((TFunctionCall) functionObj).getFunctionName().getLocation());
22043                                                        relation.addSource(element);
22044                                                }
22045                                        }
22046                                        if (functionObj instanceof TCaseExpression) {
22047                                                ResultColumn resultColumn = (ResultColumn) modelManager
22048                                                                .getModel(((TCaseExpression) functionObj).getWhenClauseItemList());
22049                                                if (resultColumn != null) {
22050                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn);
22051                                                        relation.addSource(element);
22052                                                }
22053                                        }
22054                                } else if (functionModel instanceof Table) {
22055                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
22056                                                        function.getFunctionName(), false);
22057                                        AbstractRelationship relation;
22058                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22059                                                // relation = modelFactory.createDataFlowRelation();
22060                                                relation = modelFactory.createRecordSetRelation();
22061                                        } else {
22062                                                relation = modelFactory.createRecordSetRelation();
22063                                        }
22064                                        relation.setEffectType(EffectType.function);
22065                                        relation.setFunction(function.getFunctionName().toString());
22066                                        relation.setTarget(new ResultColumnRelationshipElement(
22067                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22068                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
22069                                        relation.addSource(element);
22070                                }
22071                        }
22072                }
22073
22074                if (expr == null || "COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22075                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())
22076                                        // https://e.gitee.com/gudusoft/issues/list?issue=I4L5EO
22077                                        // 对于非 count() 函数,当有group by clause时, RelationRows 不参与indirect dataflow,
22078                                        // 让位与group by clause中的column.
22079                                        || ((TSelectSqlStatement) stmt).getGroupByClause() == null) {
22080                                TTableList tables = stmt.getTables();
22081                                if (tables != null) {
22082                                        for (int i = 0; i < tables.size(); i++) {
22083                                                TTable table = tables.getTable(i);
22084                                                if (modelManager.getModel(table) == null && table.getSubquery() == null) {
22085                                                        modelFactory.createTable(table);
22086                                                }
22087                                                if (modelManager.getModel(table) instanceof Table) {
22088                                                        Table tableModel = (Table) modelManager.getModel(table);
22089                                                        AbstractRelationship relation;
22090                                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22091                                                                // relation = modelFactory.createDataFlowRelation();
22092                                                                relation = modelFactory.createRecordSetRelation();
22093                                                        } else {
22094                                                                relation = modelFactory.createRecordSetRelation();
22095                                                        }
22096                                                        relation.setEffectType(EffectType.function);
22097                                                        relation.setFunction(function.getFunctionName().toString());
22098                                                        relation.setTarget(new ResultColumnRelationshipElement(
22099                                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22100
22101                                                        if (relation instanceof DataFlowRelationship && option.isShowCountTableColumn()) {
22102                                                                List<TExpression> expressions = new ArrayList<TExpression>();
22103                                                                getFunctionExpressions(expressions, new ArrayList<TExpression>(), function);
22104                                                                for (int j = 0; j < expressions.size(); j++) {
22105                                                                        columnsInExpr visitor = new columnsInExpr();
22106                                                                        expressions.get(j).inOrderTraverse(visitor);
22107                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
22108                                                                        if (objectNames != null) {
22109                                                                                for (TObjectName columnName : objectNames) {
22110                                                                                        TTable tempTable = modelManager.getTable(stmt, columnName);
22111                                                                                        if (table.equals(tempTable)) {
22112                                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel,
22113                                                                                                                columnName, false);
22114                                                                                                TableColumnRelationshipElement element = new TableColumnRelationshipElement(
22115                                                                                                                tableColumn);
22116                                                                                                relation.addSource(element);
22117                                                                                        }
22118                                                                                }
22119                                                                        }
22120                                                                }
22121                                                        }
22122                                                        if (relation.getSources().size() == 0) {
22123                                                                RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<TableRelationRows>(
22124                                                                                tableModel.getRelationRows());
22125                                                                relation.addSource(element);
22126                                                        }
22127                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
22128                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(table);
22129                                                        AbstractRelationship relation;
22130                                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22131                                                                // relation = modelFactory.createDataFlowRelation();
22132                                                                relation = modelFactory.createRecordSetRelation();
22133                                                        } else {
22134                                                                relation = modelFactory.createRecordSetRelation();
22135                                                        }
22136                                                        relation.setEffectType(EffectType.function);
22137                                                        relation.setFunction(function.getFunctionName().toString());
22138                                                        relation.setTarget(new ResultColumnRelationshipElement(
22139                                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22140                                                        RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<ResultSetRelationRows>(
22141                                                                        tableModel.getRelationRows());
22142                                                        relation.addSource(element);
22143                                                }
22144                                        }
22145                                }
22146                        }
22147
22148                        if (stmt.getWhereClause() == null || stmt.getWhereClause().getCondition() == null) {
22149                                return;
22150                        }
22151
22152                        columnsInExpr visitor = new columnsInExpr();
22153                        stmt.getWhereClause().getCondition().inOrderTraverse(visitor);
22154                        List<TObjectName> objectNames = visitor.getObjectNames();
22155                        for (int j = 0; j < objectNames.size(); j++) {
22156                                TObjectName columnName = objectNames.get(j);
22157                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
22158                                        Variable tableModel;
22159                                        if (columnName.toString().indexOf(".") != -1) {
22160                                                List<String> splits = SQLUtil.parseNames(columnName.toString());
22161                                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
22162                                        } else {
22163                                                tableModel = modelFactory.createVariable(columnName);
22164                                        }
22165                                        tableModel.setCreateTable(true);
22166                                        tableModel.setSubType(SubType.record);
22167                                        TObjectName variableProperties = new TObjectName();
22168                                        variableProperties.setString("*");
22169                                        modelFactory.createTableColumn(tableModel, variableProperties, true);
22170                                }
22171
22172//                              if (columnName.getColumnNameOnly().startsWith("@")
22173//                                              && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
22174//                                      continue;
22175//                              }
22176//
22177//                              if (columnName.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
22178//                                      continue;
22179//                              }
22180
22181                                AbstractRelationship relation = modelFactory.createRecordSetRelation();
22182                                relation.setEffectType(EffectType.function);
22183                                relation.setFunction(function.getFunctionName().toString());
22184                                relation.setTarget(new ResultColumnRelationshipElement(
22185                                                (ResultColumn) modelManager.getModel(function.getFunctionName())));
22186
22187                                TTable table = modelManager.getTable(stmt, columnName);
22188                                if (table != null) {
22189                                        if (modelManager.getModel(table) instanceof Table) {
22190                                                Table tableModel = (Table) modelManager.getModel(table);
22191                                                if (tableModel != null) {
22192                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
22193                                                        if(columnModel == null) {
22194                                                                continue;
22195                                                        }
22196                                                        relation.addSource(
22197                                                                        new TableColumnRelationshipElement(columnModel, columnName.getLocation()));
22198                                                }
22199                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
22200                                                Object model = modelManager.getModel(columnName.getSourceColumn());
22201                                                if (model instanceof ResultColumn) {
22202                                                        ResultColumn resultColumn = (ResultColumn) model;
22203                                                        if (resultColumn != null) {
22204                                                                relation.addSource(
22205                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
22206                                                        }
22207                                                }
22208                                        }
22209                                }
22210                        }
22211                }
22212        }
22213
22214        private void analyzeFilterCondition(Object modelObject, TExpression expr, EJoinType joinType,
22215                        JoinClauseType joinClauseType, EffectType effectType) {
22216                if (expr == null) {
22217                        return;
22218                }
22219
22220                TCustomSqlStatement stmt = stmtStack.peek();
22221
22222                columnsInExpr visitor = new columnsInExpr();
22223                expr.inOrderTraverse(visitor);
22224
22225                List<TObjectName> objectNames = visitor.getObjectNames();
22226                List<TParseTreeNode> functions = visitor.getFunctions();
22227                List<TResultColumn> resultColumns = visitor.getResultColumns();
22228                List<TParseTreeNode> constants = visitor.getConstants();
22229
22230                ImpactRelationship relation = modelFactory.createImpactRelation();
22231                relation.setEffectType(effectType);
22232                relation.setJoinClauseType(joinClauseType);
22233                if (modelObject instanceof ResultColumn) {
22234                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
22235                } else {
22236                        ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
22237                        if (resultSet == null && stmt instanceof TUpdateSqlStatement) {
22238                                resultSet = (ResultSet) modelManager.getModel(stmt);
22239                        }
22240                        if (resultSet == null && stmt instanceof TMergeSqlStatement) {
22241                                TSelectSqlStatement subquery = ((TMergeSqlStatement) stmt).getUsingTable().getSubquery();
22242                                if (subquery != null) {
22243                                        resultSet = (ResultSet) modelManager.getModel(((TMergeSqlStatement) stmt).getUsingTable());
22244                                }
22245                                else {
22246                                        resultSet = modelFactory.createQueryTable(((TMergeSqlStatement) stmt).getUsingTable());
22247                                }
22248                        }
22249                        if (resultSet != null) {
22250                                relation.setTarget(
22251                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
22252                        }
22253                        if (stmt instanceof TDeleteSqlStatement) {
22254                                Table table = (Table) modelManager.getModel(((TDeleteSqlStatement) stmt).getTargetTable());
22255                                if (table != null) {
22256                                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(table.getRelationRows()));
22257                                }
22258                        }
22259                }
22260                if (relation.getTarget() != null) {
22261
22262                        if (constants != null && constants.size() > 0) {
22263                                if (option.isShowConstantTable()) {
22264                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
22265                                        for (int i = 0; i < constants.size(); i++) {
22266                                                TParseTreeNode constant = constants.get(i);
22267                                                if (constant instanceof TConstant) {
22268                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
22269                                                                        (TConstant) constant);
22270                                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
22271                                                } else if (constant instanceof TObjectName) {
22272                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
22273                                                                        (TObjectName) constant, false);
22274                                                        if(constantColumn == null) {
22275                                                                continue;
22276                                                        }
22277                                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
22278                                                }
22279                                        }
22280                                }
22281                        }
22282
22283                        for (int j = 0; j < objectNames.size(); j++) {
22284                                TObjectName columnName = objectNames.get(j);
22285                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
22286                                        Variable variable = modelFactory.createVariable(columnName);
22287                                        variable.setSubType(SubType.record);
22288                                        if (variable.getColumns().isEmpty()) {
22289                                                TObjectName variableProperties = new TObjectName();
22290                                                variableProperties.setString("*");
22291                                                modelFactory.createTableColumn(variable, variableProperties, true);
22292                                        }
22293                                        relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0), columnName.getLocation()));
22294                                        continue;
22295                                }
22296
22297                                if (columnName.getColumnNameOnly().startsWith("@")
22298                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
22299                                        continue;
22300                                }
22301
22302                                if (columnName.getColumnNameOnly().startsWith(":")
22303                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
22304                                        continue;
22305                                }
22306
22307                                TTable table = modelManager.getTable(stmt, columnName);
22308
22309                                if (table == null) {
22310                                        table = columnName.getSourceTable();
22311                                }
22312
22313                                if (table == null && stmt.tables != null) {
22314                                        for (int k = 0; k < stmt.tables.size(); k++) {
22315                                                if (table != null)
22316                                                        break;
22317
22318                                                TTable tTable = stmt.tables.getTable(k);
22319                                                if (tTable.getTableType().name().startsWith("open")) {
22320                                                        continue;
22321                                                } else if (tTable.getLinkedColumns() != null && tTable.getLinkedColumns().size() > 0) {
22322                                                        for (int z = 0; z < tTable.getLinkedColumns().size(); z++) {
22323                                                                TObjectName refer = tTable.getLinkedColumns().getObjectName(z);
22324                                                                if ("*".equals(getColumnName(refer)))
22325                                                                        continue;
22326                                                                if (getColumnName(refer).equals(getColumnName(columnName))) {
22327                                                                        table = tTable;
22328                                                                        break;
22329                                                                }
22330                                                        }
22331                                                } else if (columnName.getTableToken() != null
22332                                                                && (columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getName())
22333                                                                                || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) {
22334                                                        table = tTable;
22335                                                        break;
22336                                                }
22337                                        }
22338
22339                                        if (table == null) {
22340                                                for (int k = 0; k < stmt.tables.size(); k++) {
22341                                                        if (table != null)
22342                                                                break;
22343
22344                                                        TTable tTable = stmt.tables.getTable(k);
22345                                                        Object model = ModelBindingManager.get().getModel(tTable);
22346                                                        if (model instanceof Table) {
22347                                                                Table tableModel = (Table) model;
22348                                                                for (int z = 0; tableModel.getColumns() != null
22349                                                                                && z < tableModel.getColumns().size(); z++) {
22350                                                                        TableColumn refer = tableModel.getColumns().get(z);
22351                                                                        if (getColumnName(refer.getName()).equals(getColumnName(columnName))) {
22352                                                                                table = tTable;
22353                                                                                break;
22354                                                                        }
22355                                                                        if (refer.hasStarLinkColumn()) {
22356                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
22357                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
22358                                                                                                table = tTable;
22359                                                                                                break;
22360                                                                                        }
22361                                                                                }
22362                                                                        }
22363                                                                }
22364                                                        } else if (model instanceof QueryTable) {
22365                                                                QueryTable tableModel = (QueryTable) model;
22366                                                                for (int z = 0; tableModel.getColumns() != null
22367                                                                                && z < tableModel.getColumns().size(); z++) {
22368                                                                        ResultColumn refer = tableModel.getColumns().get(z);
22369                                                                        if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals(
22370                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
22371                                                                                table = tTable;
22372                                                                                break;
22373                                                                        }
22374                                                                        if (refer.hasStarLinkColumn()) {
22375                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
22376                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
22377                                                                                                table = tTable;
22378                                                                                                break;
22379                                                                                        }
22380                                                                                }
22381                                                                        }
22382                                                                }
22383                                                        }
22384                                                }
22385                                        }
22386                                }
22387
22388                                if (table == null && stmt.tables != null && stmt.tables.size() != 0
22389                                                && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) {
22390                                        
22391                                        if (modelManager.getModel(stmt) instanceof ResultSet) {
22392                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt);
22393                                                boolean find = false;
22394                                                for (ResultColumn resultColumn : resultSetModel.getColumns()) {
22395                                                        if(resultColumn.equals(modelObject)) {
22396                                                                continue;
22397                                                        }
22398                                                        if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) {
22399                                                                if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) {
22400                                                                        if (resultColumn.getColumnObject() != null) {
22401                                                                                int startToken = resultColumn.getColumnObject().getStartToken().posinlist;
22402                                                                                int endToken = resultColumn.getColumnObject().getEndToken().posinlist;
22403                                                                                if (columnName.getStartToken().posinlist >= startToken
22404                                                                                                && columnName.getEndToken().posinlist <= endToken) {
22405                                                                                        continue;
22406                                                                                }
22407                                                                        }
22408                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
22409                                                                        find = true;
22410                                                                        break;
22411                                                                }
22412                                                        }
22413                                                }
22414                                                if (find) {
22415                                                        continue;
22416                                                }
22417                                        }
22418
22419                                        TObjectName pseudoTableName = new TObjectName();
22420                                        // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl)
22421                                        // Otherwise fall back to default pseudo table name
22422                                        String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName);
22423                                        pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column");
22424                                        Table pseudoTable = modelFactory.createTableByName(pseudoTableName);
22425                                        pseudoTable.setPseudo(true);
22426                                        TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true);
22427
22428                                        // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col),
22429                                        // add the pseudo table column as source
22430                                        if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) {
22431                                                relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn));
22432                                        }
22433
22434                                        if (isLinkOrphanColumnToFirstTable()) {
22435                                                TTable orphanTable = stmt.tables.getTable(0);
22436                                                table = stmt.tables.getTable(0);
22437                                                Object tableModel = modelManager.getModel(table);
22438                                                if (tableModel == null) {
22439                                                        tableModel = modelFactory.createTable(orphanTable);
22440                                                }
22441                                                if (tableModel instanceof Table) {
22442                                                        modelFactory.createTableColumn((Table) tableModel, columnName, false);
22443                                                        ErrorInfo errorInfo = new ErrorInfo();
22444                                                        errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN);
22445                                                        errorInfo.setErrorMessage("Link orphan column [" + columnName.toString()
22446                                                                        + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]");
22447                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo,
22448                                                                        columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
22449                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo,
22450                                                                        columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(),
22451                                                                        ModelBindingManager.getGlobalHash()));
22452                                                        errorInfo.fillInfo(this);
22453                                                        errorInfos.add(errorInfo);
22454                                                }
22455                                        }
22456                                }
22457
22458                                if (table != null) {
22459                                        if (modelManager.getModel(table) instanceof Table) {
22460                                                Table tableModel = (Table) modelManager.getModel(table);
22461                                                if (tableModel != null) {
22462                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
22463                                                        if(columnModel!=null) {
22464                                                                TableColumnRelationshipElement element = new TableColumnRelationshipElement(columnModel,
22465                                                                                columnName.getLocation());
22466                                                                relation.addSource(element);
22467                                                        }
22468                                                }
22469                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
22470                                                QueryTable tableModel = (QueryTable)modelManager.getModel(table);
22471                                                if (table.getSubquery() != null && table.getSubquery().isCombinedQuery()) {
22472                                                        TSelectSqlStatement subquery = table.getSubquery();
22473                                                        List<ResultSet> resultSets = new ArrayList<ResultSet>();
22474                                                        if (!subquery.getLeftStmt().isCombinedQuery()) {
22475                                                                ResultSet sourceResultSet = (ResultSet) modelManager
22476                                                                                .getModel(subquery.getLeftStmt().getResultColumnList());
22477                                                                resultSets.add(sourceResultSet);
22478                                                        } else {
22479                                                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getLeftStmt());
22480                                                                resultSets.add(sourceResultSet);
22481                                                        }
22482
22483                                                        if (!subquery.getRightStmt().isCombinedQuery()) {
22484                                                                ResultSet sourceResultSet = (ResultSet) modelManager
22485                                                                                .getModel(subquery.getRightStmt().getResultColumnList());
22486                                                                resultSets.add(sourceResultSet);
22487                                                        } else {
22488                                                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getRightStmt());
22489                                                                resultSets.add(sourceResultSet);
22490                                                        }
22491
22492                                                        for (ResultSet sourceResultSet : resultSets) {
22493                                                                if (sourceResultSet != null && columnName.getSourceColumn() != null) {
22494                                                                        for (int k = 0; k < sourceResultSet.getColumns().size(); k++) {
22495                                                                                if (getColumnName(sourceResultSet.getColumns().get(k).getName()).equals(
22496                                                                                                getColumnName(columnName.getSourceColumn().getColumnNameOnly()))) {
22497                                                                                        Set<TObjectName> starLinkColumnSet = sourceResultSet.getColumns().get(k)
22498                                                                                                        .getStarLinkColumns().get(getColumnName(columnName));
22499                                                                                        if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) {
22500                                                                                                ResultColumn column = modelFactory.createResultColumn(sourceResultSet,
22501                                                                                                                starLinkColumnSet.iterator().next(), true);
22502                                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
22503                                                                                        } else {
22504                                                                                                relation.addSource(new ResultColumnRelationshipElement(
22505                                                                                                                sourceResultSet.getColumns().get(k)));
22506                                                                                        }
22507                                                                                }
22508                                                                        }
22509                                                                }
22510                                                        }
22511                                                } else {
22512                                                        Object model = modelManager.getModel(columnName.getSourceColumn());
22513                                                        if (model instanceof ResultColumn) {
22514                                                                ResultColumn resultColumn = (ResultColumn) model;
22515                                                                if (resultColumn != null) {
22516                                                                        if (resultColumn.hasStarLinkColumn()) {
22517                                                                                Set<TObjectName> starLinkColumnSet = resultColumn.getStarLinkColumns()
22518                                                                                                .get(getColumnName(columnName));
22519                                                                                if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) {
22520                                                                                        ResultColumn column = modelFactory.createResultColumn(
22521                                                                                                        resultColumn.getResultSet(), starLinkColumnSet.iterator().next(), true);
22522                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
22523                                                                                } else {
22524                                                                                        resultColumn.bindStarLinkColumn(columnName);
22525                                                                                        ResultColumn column = modelFactory
22526                                                                                                        .createResultColumn(resultColumn.getResultSet(), columnName, true);
22527                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
22528                                                                                }
22529                                                                        } else {
22530                                                                                ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
22531                                                                                                resultColumn, columnName.getLocation());
22532                                                                                relation.addSource(element);
22533                                                                        }
22534                                                                }
22535                                                        }
22536                                                        else{
22537                                                                boolean find = false;
22538                                                                for (int i = 0; i < tableModel.getColumns().size(); i++) {
22539                                                                        ResultColumn resultColumn = tableModel.getColumns().get(i);
22540                                                                        if (DlineageUtil.getIdentifierNormalColumnName(resultColumn.getName()).equals(
22541                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
22542                                                                                ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
22543                                                                                                resultColumn, columnName.getLocation());
22544                                                                                relation.addSource(element);
22545                                                                                find = true;
22546                                                                                break;
22547                                                                        }
22548                                                                        else if (resultColumn.getName().endsWith("*")) {
22549                                                                                resultColumn.bindStarLinkColumn(columnName);
22550                                                                        }
22551                                                                }
22552                                                                if(!find){
22553                                                                        ResultColumn resultColumn = new ResultColumn(tableModel, columnName);
22554                                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
22555                                                                                                resultColumn, columnName.getLocation());
22556                                                                                relation.addSource(element);
22557                                                                }
22558                                                        }
22559                                                }
22560                                        }
22561                                }
22562                        }
22563
22564                        for (int j = 0; j < functions.size(); j++) {
22565                                TParseTreeNode functionObj = functions.get(j);
22566                                Object functionModel = modelManager.getModel(functionObj);
22567                                if (functionModel == null) {
22568                                        functionModel = createFunction(functionObj);
22569                                }
22570                                if (functionModel instanceof Function) {
22571                                        if (functionObj instanceof TFunctionCall) {
22572                                                ResultColumn resultColumn = (ResultColumn) modelManager
22573                                                                .getModel(((TFunctionCall) functionObj).getFunctionName());
22574                                                if (resultColumn != null) {
22575                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn,
22576                                                                        ((TFunctionCall) functionObj).getFunctionName().getLocation());
22577                                                        relation.addSource(element);
22578                                                }
22579                                        }
22580                                        if (functionObj instanceof TCaseExpression) {
22581                                                ResultColumn resultColumn = (ResultColumn) modelManager
22582                                                                .getModel(((TCaseExpression) functionObj).getWhenClauseItemList());
22583                                                if (resultColumn != null) {
22584                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn);
22585                                                        relation.addSource(element);
22586                                                }
22587                                        }
22588                                } else if (functionModel instanceof Table) {
22589                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
22590                                                        ((TFunctionCall) functionObj).getFunctionName(), false);
22591                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
22592                                        relation.addSource(element);
22593                                }
22594                        }
22595
22596                        for (int j = 0; j < resultColumns.size(); j++) {
22597                                TResultColumn resultColumn = resultColumns.get(j);
22598                                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
22599                                        ResultColumn resultColumnModel = (ResultColumn) modelManager.getModel(resultColumn);
22600                                        relation.addSource(new ResultColumnRelationshipElement(resultColumnModel, ESqlClause.selectList));
22601                                }
22602                        }
22603                }
22604
22605                if (isShowJoin() && joinClauseType != null) {
22606                        joinInExpr joinVisitor = new joinInExpr(joinType, joinClauseType, effectType);
22607                        expr.inOrderTraverse(joinVisitor);
22608                }
22609        }
22610
22611        public void dispose() {
22612                appendResultSets.clear();
22613                appendStarColumns.clear();
22614                appendTableStarColumns.clear();
22615                modelManager.DISPLAY_ID.clear();
22616                modelManager.DISPLAY_NAME.clear();
22617                tableIds.clear();
22618                ModelBindingManager.remove();
22619        }
22620
22621        class joinTreatColumnsInExpr implements IExpressionVisitor {
22622
22623                private List<TObjectName> objectNames = new ArrayList<TObjectName>();
22624                
22625                private TTable table;
22626
22627                public joinTreatColumnsInExpr(TTable table) {
22628                        this.table = table;
22629                }
22630
22631                public List<TObjectName> getObjectNames() {
22632                        return objectNames;
22633                }
22634
22635                boolean is_compare_condition(EExpressionType t) {
22636                        return t == EExpressionType.simple_comparison_t;
22637                }
22638
22639                @Override
22640                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
22641                        TExpression expr = (TExpression) pNode;
22642                        if (is_compare_condition(expr.getExpressionType())) {
22643                                TExpression leftExpr = expr.getLeftOperand();
22644                                columnsInExpr leftVisitor = new columnsInExpr();
22645                                leftExpr.inOrderTraverse(leftVisitor);
22646                                List<TObjectName> leftObjectNames = leftVisitor.getObjectNames();
22647
22648                                TExpression rightExpr = expr.getRightOperand();
22649                                columnsInExpr rightVisitor = new columnsInExpr();
22650                                rightExpr.inOrderTraverse(rightVisitor);
22651                                List<TObjectName> rightObjectNames = rightVisitor.getObjectNames();
22652
22653                                if (!leftObjectNames.isEmpty() && !rightObjectNames.isEmpty()) {
22654                                        for (TObjectName column : leftObjectNames) {
22655                                                if (column.getSourceTable() != null && column.getSourceTable().equals(table)) {
22656                                                        objectNames.add(column);
22657                                                        return false;
22658                                                }
22659                                        }
22660                                        for (TObjectName column : rightObjectNames) {
22661                                                if (column.getSourceTable() != null && column.getSourceTable().equals(table)) {
22662                                                        objectNames.add(column);
22663                                                        return false;
22664                                                }
22665                                        }
22666                                }
22667                                return false;
22668                        }
22669                        return true;
22670                }
22671        }
22672        
22673        class columnsInExpr implements IExpressionVisitor {
22674
22675                private List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
22676                private List<TObjectName> objectNames = new ArrayList<TObjectName>();
22677                private List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>();
22678                private List<TResultColumn> resultColumns = new ArrayList<TResultColumn>();
22679                private List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>();
22680                private boolean skipFunction = false;
22681
22682                public void setSkipFunction(boolean skipFunction) {
22683                        this.skipFunction = skipFunction;
22684                }
22685
22686                public List<TParseTreeNode> getFunctions() {
22687                        return functions;
22688                }
22689
22690                public List<TSelectSqlStatement> getSubquerys() {
22691                        return subquerys;
22692                }
22693
22694                public List<TParseTreeNode> getConstants() {
22695                        return constants;
22696                }
22697
22698                public List<TObjectName> getObjectNames() {
22699                        return objectNames;
22700                }
22701
22702                public List<TResultColumn> getResultColumns() {
22703                        return resultColumns;
22704                }
22705
22706                @Override
22707                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
22708                        TExpression lcexpr = (TExpression) pNode;
22709                        if (lcexpr.getExpressionType() == EExpressionType.simple_constant_t) {
22710                                if (lcexpr.getConstantOperand() != null) {
22711                                        if(lcexpr.getConstantOperand().getInt64_expression()!=null 
22712                                                        && lcexpr.getConstantOperand().getInt64_expression().getExpressionType() == EExpressionType.function_t) {
22713                                                lcexpr.getConstantOperand().getInt64_expression().inOrderTraverse(this);
22714                                        }
22715                                        else {
22716                                                constants.add(lcexpr.getConstantOperand());
22717                                        }
22718                                }
22719                        } else if (lcexpr.getExpressionType() == EExpressionType.array_t) {
22720                                if(lcexpr.getObjectOperand()!=null) {
22721                                        TObjectName object = lcexpr.getObjectOperand();
22722                                        objectNames.add(object);
22723                                } else if (lcexpr.getExprList() != null) {
22724                                        for (int j = 0; j < lcexpr.getExprList().size(); j++) {
22725                                                TExpression expr = lcexpr.getExprList().getExpression(j);
22726                                                if (expr != null)
22727                                                        expr.inOrderTraverse(this);
22728                                        }
22729                                }
22730                        } else if (lcexpr.getExpressionType() == EExpressionType.simple_object_name_t) {
22731                                if (lcexpr.getObjectOperand() != null && !(isBuiltInFunctionName(lcexpr.getObjectOperand())
22732                                                && isFromFunction(lcexpr.getObjectOperand()))) {
22733                                        TObjectName object = lcexpr.getObjectOperand();
22734                                        if (object.getDbObjectType() == EDbObjectType.column
22735                                                        || object.getDbObjectType() == EDbObjectType.column_alias
22736                                                        || object.getDbObjectType() == EDbObjectType.alias
22737                                                        || object.getDbObjectType() == EDbObjectType.unknown
22738                                                        || object.getDbObjectType() == EDbObjectType.variable) {
22739                                                objectNames.add(object);
22740                                        } else if (object.getDbObjectType() == EDbObjectType.notAColumn 
22741                                                        || object.getDbObjectType() == EDbObjectType.date_time_part ) {
22742                                                constants.add(object);
22743                                        }
22744                                }
22745                        } else if (lcexpr.getExpressionType() == EExpressionType.between_t) {
22746                                if (lcexpr.getBetweenOperand() != null && lcexpr.getBetweenOperand().getObjectOperand() != null) {
22747                                        TObjectName object = lcexpr.getBetweenOperand().getObjectOperand();
22748                                        if (object.getDbObjectType() == EDbObjectType.column
22749                                                        || object.getDbObjectType() == EDbObjectType.column_alias
22750                                                        || object.getDbObjectType() == EDbObjectType.alias
22751                                                        || object.getDbObjectType() == EDbObjectType.unknown
22752                                                        || object.getDbObjectType() == EDbObjectType.variable) {
22753                                                objectNames.add(object);
22754                                        }
22755                                }
22756                        } else if (lcexpr.getExpressionType() == EExpressionType.object_access_t) {
22757                                if (lcexpr.getObjectAccess() != null) {
22758                                        TObjectNameList objects = lcexpr.getObjectAccess().getAttributes();
22759                                        TFunctionCall function = lcexpr.getObjectAccess().getObjectExpr().getFunctionCall();
22760                                        if (objects != null && function != null) {
22761                                                for (TObjectName object : objects) {
22762                                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
22763                                                        sqlparser.sqltext = "select " + function.getFunctionName().toString() + "."
22764                                                                        + object.getColumnNameOnly() + " from " + function.getFunctionName().toString();
22765                                                        if (sqlparser.parse() == 0) {
22766                                                                TObjectName objectName = sqlparser.sqlstatements.get(0).getResultColumnList()
22767                                                                                .getResultColumn(0).getFieldAttr();
22768                                                                objectNames.add(objectName);
22769                                                        }
22770                                                }
22771                                        }
22772                                }
22773                        } else if (lcexpr.getExpressionType() == EExpressionType.function_t || lcexpr.getExpressionType() == EExpressionType.fieldselection_t) {
22774                                TFunctionCall func = lcexpr.getFunctionCall();
22775                                if (func == null) {
22776                                        return true;
22777                                }
22778                                if (skipFunction) {
22779                                        if (func.getArgs() != null) {
22780                                                for (int k = 0; k < func.getArgs().size(); k++) {
22781                                                        TExpression expr = func.getArgs().getExpression(k);
22782                                                        if (expr != null)
22783                                                                expr.inOrderTraverse(this);
22784                                                }
22785                                        }
22786
22787                                        if (func.getTrimArgument() != null) {
22788                                                TTrimArgument args = func.getTrimArgument();
22789                                                TExpression expr = args.getStringExpression();
22790                                                if (expr != null) {
22791                                                        expr.inOrderTraverse(this);
22792                                                }
22793                                                expr = args.getTrimCharacter();
22794                                                if (expr != null) {
22795                                                        expr.inOrderTraverse(this);
22796                                                }
22797                                        }
22798
22799                                        if (func.getAgainstExpr() != null) {
22800                                                func.getAgainstExpr().inOrderTraverse(this);
22801                                        }
22802//                                      if (func.getBetweenExpr() != null) {
22803//                                              func.getBetweenExpr().inOrderTraverse(this);
22804//                                      }
22805                                        if (func.getExpr1() != null) {
22806                                                func.getExpr1().inOrderTraverse(this);
22807                                        }
22808                                        if (func.getExpr2() != null) {
22809                                                func.getExpr2().inOrderTraverse(this);
22810                                        }
22811                                        if (func.getExpr3() != null) {
22812                                                func.getExpr3().inOrderTraverse(this);
22813                                        }
22814                                        if (func.getParameter() != null) {
22815                                                func.getParameter().inOrderTraverse(this);
22816                                        }
22817                                } else {
22818                                        functions.add(func);
22819                                }
22820
22821                        } else if (lcexpr.getExpressionType() == EExpressionType.case_t) {
22822                                TCaseExpression expr = lcexpr.getCaseExpression();
22823                                if (skipFunction) {
22824                                        TExpression defaultExpr = expr.getElse_expr();
22825                                        if (defaultExpr != null) {
22826                                                defaultExpr.inOrderTraverse(this);
22827                                        }
22828                                        TWhenClauseItemList list = expr.getWhenClauseItemList();
22829                                        for (int i = 0; i < list.size(); i++) {
22830                                                TWhenClauseItem element = (TWhenClauseItem) list.getElement(i);
22831                                                (((TWhenClauseItem) element).getReturn_expr()).inOrderTraverse(this);
22832
22833                                        }
22834                                } else {
22835                                        functions.add(expr);
22836                                }
22837                        } else if (lcexpr.getSubQuery() != null) {
22838                                TSelectSqlStatement select = lcexpr.getSubQuery();
22839                                analyzeSelectStmt(select);
22840                                subquerys.add(select);
22841                                if (select.getResultColumnList() != null && select.getResultColumnList().size() > 0) {
22842                                        for (TResultColumn column : select.getResultColumnList()) {
22843                                                resultColumns.add(column);
22844                                        }
22845                                }
22846                        }
22847                        return true;
22848                }
22849        }
22850
22851        class joinInExpr implements IExpressionVisitor {
22852
22853                private EJoinType joinType;
22854                private JoinClauseType joinClauseType;
22855                private EffectType effectType;
22856
22857                public joinInExpr(EJoinType joinType, JoinClauseType joinClauseType, EffectType effectType) {
22858                        this.joinType = joinType;
22859                        this.joinClauseType = joinClauseType;
22860                        this.effectType = effectType;
22861                }
22862
22863                boolean is_compare_condition(EExpressionType t) {
22864                        return ((t == EExpressionType.simple_comparison_t) || (t == EExpressionType.group_comparison_t)
22865                                        || (t == EExpressionType.in_t) || (t == EExpressionType.pattern_matching_t)
22866                                        || (t == EExpressionType.left_join_t) || (t == EExpressionType.right_join_t));
22867                }
22868
22869                @Override
22870                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
22871                        TExpression expr = (TExpression) pNode;
22872                        if (is_compare_condition(expr.getExpressionType())) {
22873                                TExpression leftExpr = expr.getLeftOperand();
22874                                columnsInExpr leftVisitor = new columnsInExpr();
22875                                leftExpr.inOrderTraverse(leftVisitor);
22876                                List<TObjectName> leftObjectNames = leftVisitor.getObjectNames();
22877                                List<TParseTreeNode> leftObjects = leftVisitor.getFunctions();
22878                                leftObjects.addAll(leftObjectNames);
22879                                
22880                                TExpression rightExpr = expr.getRightOperand();
22881                                columnsInExpr rightVisitor = new columnsInExpr();
22882                                rightExpr.inOrderTraverse(rightVisitor);
22883                                List<TObjectName> rightObjectNames = rightVisitor.getObjectNames();
22884                                List<TParseTreeNode> rightObjects = rightVisitor.getFunctions();
22885                                rightObjects.addAll(rightObjectNames);
22886
22887                                if (!leftObjects.isEmpty() && !rightObjects.isEmpty()) {
22888                                        TCustomSqlStatement stmt = stmtStack.peek();
22889
22890                                        for (int i = 0; i < leftObjects.size(); i++) {
22891                                                TParseTreeNode leftObject = leftObjects.get(i);
22892                                                TTable leftTable = null;
22893                                                TFunctionCall leftFunction = null;
22894                                                TObjectName leftObjectName = null;
22895                                                if (leftObject instanceof TObjectName) {
22896                                                        leftObjectName = (TObjectName)leftObject;
22897
22898                                                        if (leftObjectName.getDbObjectType() == EDbObjectType.variable) {
22899                                                                continue;
22900                                                        }
22901
22902                                                        if (leftObjectName.getColumnNameOnly().startsWith("@")
22903                                                                        && (option.getVendor() == EDbVendor.dbvmssql
22904                                                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
22905                                                                continue;
22906                                                        }
22907
22908                                                        if (leftObjectName.getColumnNameOnly().startsWith(":")
22909                                                                        && (option.getVendor() == EDbVendor.dbvhana
22910                                                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
22911                                                                continue;
22912                                                        }
22913
22914                                                        leftTable = modelManager.getTable(stmt, leftObjectName);
22915
22916                                                        if (leftTable == null) {
22917                                                                leftTable = leftObjectName.getSourceTable();
22918                                                        }
22919
22920                                                        if (leftTable == null) {
22921                                                                leftTable = modelManager.guessTable(stmt, leftObjectName);
22922                                                        }
22923                                                }
22924                                                else if(leftObject instanceof TFunctionCall){
22925                                                        leftFunction = (TFunctionCall)leftObject;
22926                                                }
22927
22928                                                if (leftTable != null || leftFunction != null) {
22929                                                        for (int j = 0; j < rightObjects.size(); j++) {
22930                                                                JoinRelationship joinRelation = modelFactory.createJoinRelation();
22931                                                                joinRelation.setEffectType(effectType);
22932                                                                if (joinType != null) {
22933                                                                        joinRelation.setJoinType(joinType);
22934                                                                } else {
22935                                                                        if (expr.getLeftOperand().isOracleOuterJoin()) {
22936                                                                                joinRelation.setJoinType(right);
22937                                                                        } else if (expr.getRightOperand().isOracleOuterJoin()) {
22938                                                                                joinRelation.setJoinType(EJoinType.left);
22939                                                                        } else if (expr.getExpressionType() == EExpressionType.left_join_t) {
22940                                                                                joinRelation.setJoinType(EJoinType.left);
22941                                                                        } else if (expr.getExpressionType() == EExpressionType.right_join_t) {
22942                                                                                joinRelation.setJoinType(right);
22943                                                                        } else {
22944                                                                                joinRelation.setJoinType(EJoinType.inner);
22945                                                                        }
22946                                                                }
22947
22948                                                                joinRelation.setJoinClauseType(joinClauseType);
22949                                                                joinRelation.setJoinCondition(expr.toString());
22950
22951
22952                                                                if (leftTable != null) {
22953                                                                        if (modelManager.getModel(leftTable) instanceof Table) {
22954                                                                                Table tableModel = (Table) modelManager.getModel(leftTable);
22955                                                                                if (tableModel != null) {
22956                                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel,
22957                                                                                                        leftObjectName, false);
22958                                                                                        if (columnModel != null) {
22959                                                                                                joinRelation.addSource(new TableColumnRelationshipElement(columnModel));
22960                                                                                        }
22961                                                                                }
22962                                                                        } else if (modelManager.getModel(leftTable) instanceof QueryTable) {
22963                                                                                QueryTable table = (QueryTable) modelManager.getModel(leftTable);
22964                                                                                TSelectSqlStatement subquery = table.getTableObject().getSubquery();
22965                                                                                if (subquery != null && subquery.isCombinedQuery()) {
22966                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
22967                                                                                                        leftObjectName);
22968                                                                                        if (resultColumn != null) {
22969                                                                                                joinRelation
22970                                                                                                                .addSource(new ResultColumnRelationshipElement(resultColumn));
22971                                                                                        }
22972                                                                                } else if (leftObjectName.getSourceColumn() != null) {
22973                                                                                        Object model = modelManager.getModel(leftObjectName);
22974                                                                                        if (model == null) {
22975                                                                                                model = modelFactory.createResultColumn(table, leftObjectName);
22976                                                                                        }
22977                                                                                        if (model instanceof ResultColumn) {
22978                                                                                                ResultColumn resultColumn = (ResultColumn) model;
22979                                                                                                if (resultColumn != null) {
22980                                                                                                        joinRelation.addSource(
22981                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
22982                                                                                                }
22983                                                                                        } else if (model instanceof LinkedHashMap) {
22984                                                                                                String columnName = getColumnNameOnly(leftObjectName.toString());
22985                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model;
22986                                                                                                if (resultColumns.containsKey(columnName)) {
22987                                                                                                        ResultColumn resultColumn = resultColumns.get(columnName);
22988                                                                                                        joinRelation.addSource(
22989                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
22990                                                                                                }
22991                                                                                        }
22992                                                                                } else {
22993                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
22994                                                                                                        leftObjectName);
22995                                                                                        if (resultColumn != null) {
22996                                                                                                joinRelation
22997                                                                                                                .addSource(new ResultColumnRelationshipElement(resultColumn));
22998                                                                                        }
22999                                                                                }
23000                                                                        }
23001                                                                }
23002                                                                else if(leftFunction!=null) {
23003                                                                        Object functionObj = createFunction(leftFunction);
23004                                                                        if(functionObj instanceof Function) {
23005                                                                                Function function = (Function)functionObj;
23006                                                                                joinRelation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
23007                                                                        }
23008                                                                }
23009
23010                                                                TParseTreeNode rightObject = rightObjects.get(j);
23011                                                                if(rightObject instanceof TObjectName) {
23012                                                                        TObjectName rightObjectName = (TObjectName)rightObject;
23013
23014                                                                        if (rightObjectName.getDbObjectType() == EDbObjectType.variable) {
23015                                                                                continue;
23016                                                                        }
23017
23018                                                                        if (rightObjectName.getColumnNameOnly().startsWith("@")
23019                                                                                        && (option.getVendor() == EDbVendor.dbvmssql
23020                                                                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
23021                                                                                continue;
23022                                                                        }
23023
23024                                                                        if (rightObjectName.getColumnNameOnly().startsWith(":")
23025                                                                                        && (option.getVendor() == EDbVendor.dbvhana
23026                                                                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
23027                                                                                continue;
23028                                                                        }
23029
23030                                                                        TTable rightTable = modelManager.getTable(stmt, rightObjectName);
23031                                                                        if (rightTable == null) {
23032                                                                                rightTable = rightObjectName.getSourceTable();
23033                                                                        }
23034
23035                                                                        if (rightTable == null) {
23036                                                                                rightTable = modelManager.guessTable(stmt, rightObjectName);
23037                                                                        }
23038
23039                                                                        if (modelManager.getModel(rightTable) instanceof Table) {
23040                                                                                Table tableModel = (Table) modelManager.getModel(rightTable);
23041                                                                                if (tableModel != null) {
23042                                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel,
23043                                                                                                        rightObjectName, false);
23044                                                                                        if(columnModel != null) {
23045                                                                                                joinRelation.setTarget(new TableColumnRelationshipElement(columnModel));
23046                                                                                        }
23047                                                                                }
23048                                                                        } else if (modelManager.getModel(rightTable) instanceof QueryTable) {
23049                                                                                QueryTable table = (QueryTable) modelManager.getModel(rightTable);
23050                                                                                TSelectSqlStatement subquery = table.getTableObject().getSubquery();
23051                                                                                if (subquery != null && subquery.isCombinedQuery()) {
23052                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
23053                                                                                                        rightObjectName);
23054                                                                                        if (resultColumn != null) {
23055                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
23056                                                                                        }
23057                                                                                } else if (rightObjectName.getSourceColumn() != null) {
23058                                                                                        Object model = modelManager.getModel(rightObjectName);
23059                                                                                        if (model == null) {
23060                                                                                                model = modelManager
23061                                                                                                                .getModel(rightObjectName.getSourceColumn());
23062                                                                                        }
23063                                                                                        if (model instanceof ResultColumn) {
23064                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement((ResultColumn)model));
23065                                                                                        }
23066                                                                                        else if (model instanceof LinkedHashMap) {
23067                                                                                                String columnName = getColumnNameOnly(rightObjectName.toString());
23068                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model;
23069                                                                                                if (resultColumns.containsKey(columnName)) {
23070                                                                                                        ResultColumn resultColumn = resultColumns.get(columnName);
23071                                                                                                        joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
23072                                                                                                }
23073                                                                                        }
23074                                                                                } else {
23075                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
23076                                                                                                        rightObjectName);
23077                                                                                        if (resultColumn != null) {
23078                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
23079                                                                                        }
23080                                                                                }
23081                                                                        }
23082                                                                }
23083                                                                else if(rightObject instanceof TFunctionCall) {
23084                                                                        Object functionObj = createFunction(rightObject);
23085                                                                        if(functionObj instanceof Function) {
23086                                                                                Function function = (Function)functionObj;
23087                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(function.getColumns().get(0)));
23088                                                                        }
23089                                                                }
23090                                                        }
23091                                                }
23092                                        }
23093                                }
23094                        }
23095                        return true;
23096                }
23097        }
23098
23099        @Deprecated
23100        public static Dataflow getSqlflowJSONModel(dataflow dataflow) {
23101                EDbVendor vendor = ModelBindingManager.getGlobalVendor();
23102                if(vendor == null) {
23103                        throw new IllegalArgumentException("getSqlflowJSONModel(dataflow dataflow) is deprecated, please call method getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor).");
23104                }
23105                return getSqlflowJSONModel(vendor, dataflow, false);
23106        }
23107
23108        public static Dataflow getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor) {
23109                return getSqlflowJSONModel(vendor, dataflow, false);
23110        }
23111
23112        public static Dataflow getSqlflowJSONModel(EDbVendor vendor, dataflow dataflow, boolean normalizeIdentifier) {
23113                Dataflow model = new Dataflow();
23114                
23115                if (dataflow.getErrors() != null && !dataflow.getErrors().isEmpty()) {
23116                        List<Error> errorList = new ArrayList<Error>();
23117                        for (error error : dataflow.getErrors()) {
23118                                Error err = new Error();
23119                                err.setErrorMessage(error.getErrorMessage());
23120                                err.setErrorType(error.getErrorType());
23121                                err.setCoordinates(Coordinate.parse(error.getCoordinate()));
23122                                err.setFile(err.getFile());
23123                                err.setOriginCoordinates(Coordinate.parse(error.getOriginCoordinate()));
23124                                errorList.add(err);
23125                        }
23126                        model.setErrors(errorList.toArray(new Error[0]));
23127                }
23128
23129                Sqlflow sqlflow = MetadataUtil.convertDataflowToMetadata(vendor, dataflow);
23130                sqlflow.setErrorMessages(null);
23131                model.setDbobjs(sqlflow);
23132                model.setOrientation(dataflow.getOrientation());
23133
23134
23135                List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process> processes = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process>();
23136                if(dataflow.getProcesses()!=null){
23137                        for(process process: dataflow.getProcesses()){
23138                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Process processModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process();
23139                                processModel.setId(process.getId());
23140                                processModel.setName(process.getName());
23141                                processModel.setProcedureId(process.getProcedureId());
23142                                processModel.setProcedureName(process.getProcedureName());
23143                                processModel.setType(process.getType());
23144                                processModel.setCoordinate(process.getCoordinate());
23145                                processModel.setDatabase(process.getDatabase());
23146                                processModel.setSchema(process.getSchema());
23147                                processModel.setServer(process.getServer());
23148                                processModel.setQueryHashId(process.getQueryHashId());
23149                                if (process.getTransforms() != null && !process.getTransforms().isEmpty()) {
23150                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>();
23151                                        for (transform transform : process.getTransforms()) {
23152                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform();
23153                                                item.setCode(transform.getCode());
23154                                                item.setType(transform.getType());
23155                                                item.setCoordinate(transform.getCoordinate(true));
23156                                                transforms.add(item);
23157                                        }
23158                                        processModel.setTransforms(transforms
23159                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0]));
23160                                }
23161                                processes.add(processModel);
23162                        }
23163                }
23164                model.setProcesses(processes.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process[0]));
23165
23166                List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship> relations = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship>();
23167                if (dataflow.getRelationships() != null) {
23168                        for (relationship relation : dataflow.getRelationships()) {
23169                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship relationModel;
23170                                if (relation.getType().equals("join")) {
23171                                        gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship joinRelationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship();
23172                                        joinRelationModel.setCondition(relation.getCondition());
23173                                        joinRelationModel.setJoinType(relation.getJoinType());
23174                                        joinRelationModel.setClause(relation.getClause());
23175                                        relationModel = joinRelationModel;
23176                                } else {
23177                                        relationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship();
23178                                }
23179
23180                                relationModel.setId(relation.getId());
23181                                relationModel.setProcessId(relation.getProcessId());
23182                                relationModel.setProcessType(relation.getProcessType());
23183                                relationModel.setType(relation.getType());
23184                                relationModel.setEffectType(relation.getEffectType());
23185                                relationModel.setPartition(relation.getPartition());
23186                                relationModel.setFunction(relation.getFunction());
23187                                relationModel.setProcedureId(relation.getProcedureId());
23188                                relationModel.setSqlHash(relation.getSqlHash());
23189                                relationModel.setCondition(relation.getCondition());
23190                                relationModel.setSqlComment(relation.getSqlComment());
23191                                relationModel.setTimestampMax(relation.getTimestampMax());
23192                                relationModel.setTimestampMin(relation.getTimestampMin());
23193                                if (Boolean.TRUE.equals(relation.getBuiltIn())) {
23194                                        relationModel.setBuiltIn(relation.getBuiltIn());
23195                                }
23196                                relationModel.setCallStmt(relation.getCallStmt());
23197                                relationModel.setCallCoordinate(relation.getCallCoordinate());
23198                                
23199                                if (relation.getTarget() != null && relation.getSources() != null && !relation.getSources().isEmpty()) {
23200                                        {
23201                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23202                                                targetColumn target = relation.getTarget();
23203                                                if (normalizeIdentifier) {
23204                                                        targetModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, target.getColumn()));
23205                                                        targetModel.setParentName(
23206                                                                        SQLUtil.getIdentifierNormalTableName(vendor, target.getParent_name()));
23207                                                        targetModel.setTargetName(
23208                                                                        SQLUtil.getIdentifierNormalColumnName(vendor, target.getTarget_name()));
23209                                                } else {
23210                                                        targetModel.setColumn(target.getColumn());
23211                                                        targetModel.setParentName(target.getParent_name());
23212                                                        targetModel.setTargetName(target.getTarget_name());
23213                                                }
23214                                                targetModel.setId(target.getId());
23215                                                targetModel.setTargetId(target.getTarget_id());
23216                                                targetModel.setParentId(target.getParent_id());
23217                                                targetModel.setCoordinates(Coordinate.parse(target.getCoordinate()));
23218                                                targetModel.setFunction(target.getFunction());
23219                                                targetModel.setType(target.getType());
23220                                                relationModel.setTarget(targetModel);
23221                                        }
23222
23223                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>();
23224                                        for (sourceColumn source : relation.getSources()) {
23225                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23226                                                if (normalizeIdentifier) {
23227                                                        sourceModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, source.getColumn()));
23228                                                        sourceModel.setParentName(
23229                                                                        SQLUtil.getIdentifierNormalTableName(vendor, source.getParent_name()));
23230                                                        sourceModel.setSourceName(
23231                                                                        SQLUtil.getIdentifierNormalColumnName(vendor, source.getSource_name()));
23232                                                } else {
23233                                                        sourceModel.setColumn(source.getColumn());
23234                                                        sourceModel.setParentName(source.getParent_name());
23235                                                        sourceModel.setSourceName(source.getSource_name());
23236                                                }
23237                                                sourceModel.setColumnType(source.getColumn_type());
23238                                                sourceModel.setId(source.getId());
23239                                                sourceModel.setParentId(source.getParent_id());
23240                                                sourceModel.setSourceId(source.getSource_id());
23241                                                sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate()));
23242                                                sourceModel.setClauseType(source.getClauseType());
23243                                                sourceModel.setType(source.getType());
23244                                                sourceModels.add(sourceModel);
23245                                                if (source.getTransforms() != null && !source.getTransforms().isEmpty()) {
23246                                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>();
23247                                                        for (transform transform : source.getTransforms()) {
23248                                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform();
23249                                                                item.setCode(transform.getCode());
23250                                                                item.setType(transform.getType());
23251                                                                item.setCoordinate(transform.getCoordinate(true));
23252                                                                transforms.add(item);
23253                                                        }
23254                                                        sourceModel.setTransforms(transforms
23255                                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0]));
23256                                                }
23257                                                
23258                                                if (source.getCandidateParents() != null && !source.getCandidateParents().isEmpty()) {
23259                                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable> candidateParents = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable>();
23260                                                        for (candidateTable candidateTable : source.getCandidateParents()) {
23261                                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable();
23262                                                                item.setId(candidateTable.getId());
23263                                                                if (normalizeIdentifier) {
23264                                                                        item.setName(
23265                                                                                        SQLUtil.getIdentifierNormalTableName(vendor, candidateTable.getName()));
23266                                                                } else {
23267                                                                        item.setName(candidateTable.getName());
23268                                                                }
23269                                                                candidateParents.add(item);
23270                                                        }
23271                                                        sourceModel.setCandidateParents(candidateParents
23272                                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable[0]));
23273                                                }
23274                                        }
23275                                        relationModel.setSources(sourceModels
23276                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0]));
23277                                        relations.add(relationModel);
23278                                } else if (relation.getCaller() != null && relation.getCallees() != null
23279                                                && !relation.getCallees().isEmpty()) {
23280                                        {
23281                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23282                                                targetColumn target = relation.getCaller();
23283                                                if (normalizeIdentifier) {
23284                                                        targetModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, target.getName()));
23285                                                } else {
23286                                                        targetModel.setName(target.getName());
23287                                                }
23288                                                targetModel.setId(target.getId());
23289                                                targetModel.setCoordinates(Coordinate.parse(target.getCoordinate()));
23290                                                targetModel.setType(target.getType());
23291                                                relationModel.setCaller(targetModel);
23292                                        }
23293
23294                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>();
23295                                        for (sourceColumn source : relation.getCallees()) {
23296                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23297                                                if (normalizeIdentifier) {
23298                                                        sourceModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, source.getName()));
23299                                                } else {
23300                                                        sourceModel.setName(source.getName());
23301                                                }
23302                                                sourceModel.setId(source.getId());
23303                                                sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate()));
23304                                                sourceModel.setType(source.getType());
23305                                                sourceModels.add(sourceModel);
23306                                        }
23307                                        relationModel.setCallees(sourceModels
23308                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0]));
23309                                        relations.add(relationModel);
23310                                }
23311                        }
23312                }
23313                model.setRelationships(relations.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship[0]));
23314                return model;
23315        }
23316
23317        public static String getVersion() {
23318                return "3.1.4";
23319        }
23320
23321        public static String getReleaseDate() {
23322                return "2023-03-04";
23323        }
23324
23325        public static void main(String[] args) {
23326                if (args.length < 1) {
23327                        System.out.println(
23328                                        "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]");
23329                        System.out.println("/f: Option, specify the sql file path to analyze fdd relation.");
23330                        System.out.println("/d: Option, specify the sql directory path to analyze fdd relation.");
23331                        System.out.println("/j: Option, analyze the join relation.");
23332                        System.out.println("/s: Option, simple output, ignore the intermediate results.");
23333                        System.out.println("/i: Option, ignore all result sets.");
23334                        System.out.println("/traceView: Option, analyze the source tables of views.");
23335                        System.out.println("/text: Option, print the plain text format output.");
23336                        System.out.println("/json: Option, print the json format output.");
23337                        System.out.println(
23338                                        "/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");
23339                        System.out.println("/o: Option, write the output stream to the specified file.");
23340                        System.out.println("/log: Option, generate a dataflow.log file to log information.");
23341                        return;
23342                }
23343
23344                File sqlFiles = null;
23345
23346                List<String> argList = Arrays.asList(args);
23347
23348                if (argList.indexOf("/version") != -1) {
23349                        System.out.println("Version: " + DataFlowAnalyzer.getVersion());
23350                        System.out.println("Release Date: " + DataFlowAnalyzer.getReleaseDate());
23351                        return;
23352                }
23353
23354                if (argList.indexOf("/f") != -1 && argList.size() > argList.indexOf("/f") + 1) {
23355                        sqlFiles = new File(args[argList.indexOf("/f") + 1]);
23356                        if (!sqlFiles.exists() || !sqlFiles.isFile()) {
23357                                System.out.println(sqlFiles + " is not a valid file.");
23358                                return;
23359                        }
23360                } else if (argList.indexOf("/d") != -1 && argList.size() > argList.indexOf("/d") + 1) {
23361                        sqlFiles = new File(args[argList.indexOf("/d") + 1]);
23362                        if (!sqlFiles.exists() || !sqlFiles.isDirectory()) {
23363                                System.out.println(sqlFiles + " is not a valid directory.");
23364                                return;
23365                        }
23366                } else {
23367                        System.out.println("Please specify a sql file path or directory path to analyze dlineage.");
23368                        return;
23369                }
23370
23371                EDbVendor vendor = EDbVendor.dbvoracle;
23372
23373                int index = argList.indexOf("/t");
23374
23375                if (index != -1 && args.length > index + 1) {
23376                        vendor = TGSqlParser.getDBVendorByName(args[index + 1]);
23377                }
23378
23379                String outputFile = null;
23380
23381                index = argList.indexOf("/o");
23382
23383                if (index != -1 && args.length > index + 1) {
23384                        outputFile = args[index + 1];
23385                }
23386
23387                FileOutputStream writer = null;
23388                if (outputFile != null) {
23389                        try {
23390                                writer = new FileOutputStream(outputFile);
23391                                System.setOut(new PrintStream(writer));
23392                        } catch (FileNotFoundException e) {
23393                                logger.error("output file is not found.", e);
23394                        }
23395                }
23396
23397                boolean simple = argList.indexOf("/s") != -1;
23398                boolean ignoreResultSets = argList.indexOf("/i") != -1;
23399                boolean showJoin = argList.indexOf("/j") != -1;
23400                boolean textFormat = false;
23401                boolean jsonFormat = false;
23402                if (simple) {
23403                        textFormat = argList.indexOf("/text") != -1;
23404                }
23405
23406                boolean traceView = argList.indexOf("/traceView") != -1;
23407                if (traceView) {
23408                        simple = true;
23409                }
23410
23411                jsonFormat = argList.indexOf("/json") != -1;
23412
23413                DataFlowAnalyzer dlineage = new DataFlowAnalyzer(sqlFiles, vendor, simple);
23414
23415                dlineage.setShowJoin(showJoin);
23416                dlineage.setIgnoreRecordSet(ignoreResultSets);
23417                // dlineage.setShowImplicitSchema(true);
23418
23419                if (simple && !jsonFormat) {
23420                        dlineage.setTextFormat(textFormat);
23421                }
23422
23423                String result = dlineage.generateDataFlow();
23424
23425//              dataflow dataflow = ProcessUtility.generateTableLevelLineage(dlineage, dlineage.getDataFlow());
23426//              System.out.println(result);
23427
23428                if (jsonFormat) {
23429                        // Map jsonResult = new LinkedHashMap();
23430                        Dataflow model = getSqlflowJSONModel(vendor, dlineage.getDataFlow(), true);
23431                        // jsonResult.put("data", BeanUtils.bean2Map(model));
23432                        result = JSON.toJSONString(model);
23433                } else if (traceView) {
23434                        result = dlineage.traceView();
23435                }
23436
23437                if (result != null) {
23438                        System.out.println(result);
23439
23440                        if (writer != null && result.length() < 1024 * 1024) {
23441                                System.err.println(result);
23442                        }
23443                }
23444
23445                try {
23446                        if (writer != null) {
23447                                writer.close();
23448                        }
23449                } catch (IOException e) {
23450                        logger.error("close writer failed.", e);
23451                }
23452
23453                boolean log = argList.indexOf("/log") != -1;
23454
23455                PrintStream systemSteam = System.err;
23456                ByteArrayOutputStream sw = new ByteArrayOutputStream();
23457                PrintStream pw = new PrintStream(sw);
23458                System.setErr(pw);
23459
23460
23461                List<ErrorInfo> errors = dlineage.getErrorMessages();
23462                if (!errors.isEmpty()) {
23463                        System.err.println("Error log:\n");
23464                        for (int i = 0; i < errors.size(); i++) {
23465                                System.err.println(errors.get(i).getErrorMessage());
23466                        }
23467                }
23468
23469                if (sw != null) {
23470                        String errorMessage = sw.toString().trim();
23471                        if (errorMessage.length() > 0) {
23472                                if (log) {
23473                                        try {
23474                                                pw = new PrintStream(new File(".", "dataflow.log"));
23475                                                pw.print(errorMessage);
23476                                        } catch (FileNotFoundException e) {
23477                                                logger.error("error log file is not found.", e);
23478                                        }
23479                                }
23480
23481                                System.setErr(systemSteam);
23482                                System.err.println(errorMessage);
23483                        }
23484                }
23485        }
23486
23487        public List<ErrorInfo> getErrorMessages() {
23488                return errorInfos;
23489        }
23490
23491        public String traceView() {
23492                StringBuilder buffer = new StringBuilder();
23493                dataflow dataflow = this.getDataFlow();
23494                Map<table, Set<table>> traceViewMap = new LinkedHashMap<table, Set<table>>();
23495                if (dataflow != null && dataflow.getViews() != null) {
23496                        List<relationship> relations = dataflow.getRelationships();
23497                        Map<String, table> viewMap = new HashMap<String, table>();
23498                        Map<String, table> tableMap = new HashMap<String, table>();
23499                        for (table view : dataflow.getViews()) {
23500                                viewMap.put(view.getId(), view);
23501                                tableMap.put(view.getId(), view);
23502                        }
23503                        for (table table : dataflow.getTables()) {
23504                                tableMap.put(table.getId(), table);
23505                        }
23506                        for (relationship relation : relations) {
23507                                if (!RelationshipType.fdd.name().equals(relation.getType())) {
23508                                        continue;
23509                                }
23510                                String parentId = relation.getTarget().getParent_id();
23511                                if (viewMap.containsKey(parentId)) {
23512                                        if (!traceViewMap.containsKey(viewMap.get(parentId))) {
23513                                                traceViewMap.put(viewMap.get(parentId), new LinkedHashSet<table>());
23514                                        }
23515
23516                                        for (sourceColumn sourceColumn : relation.getSources()) {
23517                                                traceViewMap.get(viewMap.get(parentId)).add(tableMap.get(sourceColumn.getParent_id()));
23518                                        }
23519                                }
23520                        }
23521
23522                        Map<table, Set<table>> viewTableMap = new LinkedHashMap<table, Set<table>>();
23523                        for (table view : traceViewMap.keySet()) {
23524                                Set<table> tables = new LinkedHashSet<table>();
23525                                traverseViewSourceTables(tables, view, traceViewMap);
23526                                viewTableMap.put(view, tables);
23527                        }
23528
23529                        for (table view : viewTableMap.keySet()) {
23530                                buffer.append(view.getFullName());
23531                                for (table table : viewTableMap.get(view)) {
23532                                        buffer.append(",").append(table.getFullName());
23533                                }
23534                                buffer.append(System.getProperty("line.separator"));
23535                        }
23536                }
23537                return buffer.toString().trim();
23538        }
23539
23540        private void traverseViewSourceTables(Set<table> tables, table view, Map<table, Set<table>> traceViewMap) {
23541                Set<table> sourceTables = traceViewMap.get(view);
23542                for (table sourceTable : sourceTables) {
23543                        if (sourceTable.isTable()) {
23544                                tables.add(sourceTable);
23545                        } else if (sourceTable.isView()) {
23546                                traverseViewSourceTables(tables, sourceTable, traceViewMap);
23547                        }
23548                }
23549        }
23550
23551        protected List<SqlInfo> convertSQL(EDbVendor vendor, String json) {
23552                List<SqlInfo> sqlInfos = new ArrayList<SqlInfo>();
23553                List sqlContents = (List) JSON.parseObject(json);
23554                for (int j = 0; j < sqlContents.size(); j++) {
23555                        Map sqlContent = (Map) sqlContents.get(j);
23556                        String sql = (String) sqlContent.get("sql");
23557                        String fileName = (String) sqlContent.get("fileName");
23558                        String filePath = (String) sqlContent.get("filePath");
23559                        if (sql != null && sql.trim().startsWith("{")) {
23560                                if (sql.indexOf("createdBy") != -1) {
23561                                        if (this.sqlenv == null) {
23562                                                TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(),
23563                                                                option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql);
23564                                                if (sqlenvs != null && sqlenvs.length > 0) {
23565                                                        this.sqlenv = sqlenvs[0];
23566                                                }
23567                                        }
23568                                        if (sql.toLowerCase().indexOf("sqldep") != -1 || sql.toLowerCase().indexOf("grabit") != -1) {
23569                                                Map queryObject = (Map) JSON.parseObject(sql);
23570                                                List querys = (List) queryObject.get("queries");
23571                                                if (querys != null) {
23572                                                        for (int i = 0; i < querys.size(); i++) {
23573                                                                Map object = (Map) querys.get(i);
23574                                                                SqlInfo info = new SqlInfo();
23575                                                                info.setSql(JSON.toJSONString(object));
23576                                                                info.setFileName(fileName);
23577                                                                info.setFilePath(filePath);
23578                                                                info.setOriginIndex(i);
23579                                                                sqlInfos.add(info);
23580                                                        }
23581                                                        queryObject.remove("queries");
23582                                                        SqlInfo info = new SqlInfo();
23583                                                        info.setSql(JSON.toJSONString(queryObject));
23584                                                        info.setFileName(fileName);
23585                                                        info.setFilePath(filePath);
23586                                                        info.setOriginIndex(querys.size());
23587                                                        sqlInfos.add(info);
23588                                                } else {
23589                                                        SqlInfo info = new SqlInfo();
23590                                                        info.setSql(JSON.toJSONString(queryObject));
23591                                                        info.setFileName(fileName);
23592                                                        info.setFilePath(filePath);
23593                                                        info.setOriginIndex(0);
23594                                                        sqlInfos.add(info);
23595                                                }
23596                                        } else if (sql.toLowerCase().indexOf("sqlflow") != -1) {
23597                                                Map sqlflow = (Map) JSON.parseObject(sql);
23598                                                List<Map> servers = (List<Map>) sqlflow.get("servers");
23599                                                if (servers != null) {
23600                                                        for (Map queryObject : servers) {
23601                                                                String name = (String) queryObject.get("name");
23602                                                                String dbVendor = (String) queryObject.get("dbVendor");
23603                                                                List querys = (List) queryObject.get("queries");
23604                                                                if (querys != null) {
23605                                                                        for (int i = 0; i < querys.size(); i++) {
23606                                                                                Map object = (Map) querys.get(i);
23607                                                                                SqlInfo info = new SqlInfo();
23608                                                                                info.setSql(JSON.toJSONString(object));
23609                                                                                info.setFileName(fileName);
23610                                                                                info.setFilePath(filePath);
23611                                                                                info.setOriginIndex(i);
23612                                                                                info.setDbVendor(dbVendor);
23613                                                                                info.setServer(name);
23614                                                                                sqlInfos.add(info);
23615                                                                        }
23616                                                                        queryObject.remove("queries");
23617                                                                        Map serverObject = new IndexedLinkedHashMap();
23618                                                                        serverObject.put("createdBy", sqlflow.get("createdBy"));
23619                                                                        serverObject.put("servers", Arrays.asList(queryObject));
23620                                                                        SqlInfo info = new SqlInfo();
23621                                                                        info.setSql(JSON.toJSONString(serverObject));
23622                                                                        info.setFileName(fileName);
23623                                                                        info.setFilePath(filePath);
23624                                                                        info.setOriginIndex(querys.size());
23625                                                                        info.setDbVendor(dbVendor);
23626                                                                        info.setServer(filePath);
23627                                                                        sqlInfos.add(info);
23628                                                                } else {
23629                                                                        SqlInfo info = new SqlInfo();
23630                                                                        info.setSql(JSON.toJSONString(queryObject));
23631                                                                        info.setFileName(fileName);
23632                                                                        info.setFilePath(filePath);
23633                                                                        info.setOriginIndex(0);
23634                                                                        sqlInfos.add(info);
23635                                                                }
23636                                                        }
23637                                                }
23638                                                
23639                                                List<Map> errorMessages =  (List<Map>) sqlflow.get("errorMessages");
23640                                                if(errorMessages!=null && !errorMessages.isEmpty()) {
23641                                                        for(Map error: errorMessages){
23642                                                                ErrorInfo errorInfo = new ErrorInfo();
23643                                                                errorInfo.setErrorType(ErrorInfo.METADATA_ERROR);
23644                                                                errorInfo.setErrorMessage((String)error.get("errorMessage"));
23645                                                                errorInfo.setFileName(fileName);
23646                                                                errorInfo.setFilePath(filePath);
23647                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L,
23648                                                                                ModelBindingManager.getGlobalHash()));
23649                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L,
23650                                                                                ModelBindingManager.getGlobalHash()));
23651                                                                errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L));
23652                                                                errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L));
23653                                                                metadataErrors.add(errorInfo);
23654                                                        }
23655                                                }
23656                                        }
23657                                }
23658                        } else if (sql != null) {
23659                                SqlInfo info = new SqlInfo();
23660                                info.setSql(sql);
23661                                info.setFileName(fileName);
23662                                info.setFilePath(filePath);
23663                                info.setOriginIndex(0);
23664                                sqlInfos.add(info);
23665                        }
23666                }
23667                return sqlInfos;
23668        }
23669
23670        public void setTextFormat(boolean textFormat) {
23671                option.setTextFormat(textFormat);
23672        }
23673
23674        public boolean isBuiltInFunctionName(TObjectName object) {
23675                if (object == null || object.getGsqlparser() == null)
23676                        return false;
23677                try {
23678                        EDbVendor vendor = object.getGsqlparser().getDbVendor();
23679                        if (vendor == EDbVendor.dbvteradata) {
23680                                boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(object.toString().toUpperCase());
23681                                if (result) {
23682                                        return true;
23683                                }
23684                        }
23685
23686                        List<String> versions = functionChecker.getAvailableDbVersions(vendor);
23687                        if (versions != null && versions.size() > 0) {
23688                                for (int i = 0; i < versions.size(); i++) {
23689                                        boolean result = functionChecker.isBuiltInFunction(object.toString(),
23690                                                        object.getGsqlparser().getDbVendor(), versions.get(i));
23691                                        if (result) {
23692                                                return result;
23693                                        }
23694                                }
23695
23696                                // boolean result =
23697                                // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString());
23698                                // if (result) {
23699                                // return true;
23700                                // }
23701                        }
23702                } catch (Exception e) {
23703                }
23704
23705                return false;
23706        }
23707        
23708        public boolean isBuiltInFunctionName(String functionName) {
23709                if (functionName == null)
23710                        return false;
23711                try {
23712                        EDbVendor vendor = getOption().getVendor();
23713                        if (vendor == EDbVendor.dbvteradata) {
23714                                boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(functionName.toUpperCase());
23715                                if (result) {
23716                                        return true;
23717                                }
23718                        }
23719
23720                        List<String> versions = functionChecker.getAvailableDbVersions(vendor);
23721                        if (versions != null && versions.size() > 0) {
23722                                for (int i = 0; i < versions.size(); i++) {
23723                                        boolean result = functionChecker.isBuiltInFunction(functionName.toUpperCase(),
23724                                                        vendor, versions.get(i));
23725                                        if (result) {
23726                                                return result;
23727                                        }
23728                                }
23729
23730                                // boolean result =
23731                                // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString());
23732                                // if (result) {
23733                                // return true;
23734                                // }
23735                        }
23736                } catch (Exception e) {
23737                }
23738
23739                return false;
23740        }
23741
23742        public boolean isKeyword(TObjectName object) {
23743                if (object == null || object.getGsqlparser() == null)
23744                        return false;
23745                try {
23746                        EDbVendor vendor = object.getGsqlparser().getDbVendor();
23747
23748                        List<String> versions = keywordChecker.getAvailableDbVersions(vendor);
23749                        if (versions != null && versions.size() > 0) {
23750                                for (int i = 0; i < versions.size(); i++) {
23751                                        List<String> segments = SQLUtil.parseNames(object.toString());
23752                                        boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1),
23753                                                        object.getGsqlparser().getDbVendor(), versions.get(i), true);
23754                                        if (result) {
23755                                                return result;
23756                                        }
23757                                }
23758                        }
23759                } catch (Exception e) {
23760                }
23761
23762                return false;
23763        }
23764        
23765        public boolean isKeyword(String objectName) {
23766                if (objectName == null)
23767                        return false;
23768                try {
23769                        EDbVendor vendor = getOption().getVendor();
23770
23771                        List<String> versions = keywordChecker.getAvailableDbVersions(vendor);
23772                        if (versions != null && versions.size() > 0) {
23773                                for (int i = 0; i < versions.size(); i++) {
23774                                        List<String> segments = SQLUtil.parseNames(objectName);
23775                                        boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1),
23776                                                        vendor, versions.get(i), false);
23777                                        if (result) {
23778                                                return result;
23779                                        }
23780                                }
23781                        }
23782                } catch (Exception e) {
23783                }
23784
23785                return false;
23786        }
23787
23788        public boolean isAggregateFunction(TFunctionCall func) {
23789                if (func == null)
23790                        return false;
23791                return Arrays
23792                                .asList(new String[] { "AVG", "COUNT", "MAX", "MIN", "SUM", "COLLECT", "CORR", "COVAR_POP",
23793                                                "COVAR_SAMP", "CUME_DIST", "DENSE_RANK", "FIRST", "GROUP_ID", "GROUPING", "GROUPING_ID", "LAST",
23794                                                "LISTAGG", "MEDIAN", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK",
23795                                                "STATS_BINOMIAL_TEST", "STATS_CROSSTAB", "STATS_F_TEST", "STATS_KS_TEST", "STATS_MODE",
23796                                                "STATS_MW_TEST", "STATS_ONE_WAY_ANOVA", "STATS_WSR_TEST", "STDDEV", "STDDEV_POP", "STDDEV_SAMP",
23797                                                "SYS_XMLAGG", "VAR_ POP", "VAR_ SAMP", "VARI ANCE", "XMLAGG", "ARRAY_AGG" })
23798                                .contains(func.getFunctionName().toString().toUpperCase());
23799        }
23800
23801        public boolean isConstant(TObjectName object) {
23802                if (object == null || object.getGsqlparser() == null)
23803                        return false;
23804                List<String> constants = Arrays.asList(new String[] { "NEXTVAL", "CURRVAL", "SYSDATE", "CENTURY", "YEAR",
23805                                "MONTH", "DAY", "HOUR", "MINUTE", "SECOND" });
23806                List<String> segments = SQLUtil.parseNames(object.toString());
23807                if (segments.size() > 1 && "NEXTVAL".equalsIgnoreCase(object.getColumnNameOnly())
23808                                && option.getVendor() == EDbVendor.dbvoracle) {
23809                        return false;
23810                }
23811                boolean result = constants.indexOf(segments.get(segments.size() - 1).toUpperCase()) != -1;
23812                if (result) {
23813                        return result;
23814                }
23815                if (isKeyword(object)) {
23816                        return true;
23817                }
23818                return false;
23819        }
23820
23821        private Pair3<Long, Long, Integer> convertCoordinate(Pair3<Long, Long, String> position) {
23822//              if (ModelBindingManager.getGlobalOption()!=null && ModelBindingManager.getGlobalOption().isIgnoreCoordinate()) {
23823//                      return new Pair3<>(-1L, -1L, -1);
23824//              }
23825                return new Pair3<Long, Long, Integer>(position.first, position.second,
23826                                ModelBindingManager.getGlobalSqlInfo().getIndexOf(position.third));
23827        }
23828
23829}