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.dataflow.sqlenv.model.SQLEnv;
019import gudusoft.gsqlparser.dlineage.metadata.MetadataUtil;
020import gudusoft.gsqlparser.dlineage.metadata.Sqlflow;
021import gudusoft.gsqlparser.dlineage.util.*;
022import gudusoft.gsqlparser.nodes.*;
023import gudusoft.gsqlparser.nodes.couchbase.TObjectConstruct;
024import gudusoft.gsqlparser.nodes.couchbase.TPair;
025import gudusoft.gsqlparser.nodes.functions.TJsonObjectFunction;
026import gudusoft.gsqlparser.nodes.hive.THiveTransformClause;
027import gudusoft.gsqlparser.nodes.hive.THiveTransformClause.ETransformType;
028import gudusoft.gsqlparser.sqlenv.TSQLEnv;
029import gudusoft.gsqlparser.sqlenv.TSQLSchema;
030import gudusoft.gsqlparser.sqlenv.TSQLTable;
031import gudusoft.gsqlparser.sqlenv.parser.TJSONSQLEnvParser;
032import gudusoft.gsqlparser.stmt.*;
033import gudusoft.gsqlparser.stmt.db2.TDb2ReturnStmt;
034import gudusoft.gsqlparser.stmt.db2.TDb2SqlVariableDeclaration;
035import gudusoft.gsqlparser.stmt.hive.THiveLoad;
036import gudusoft.gsqlparser.stmt.mssql.*;
037import gudusoft.gsqlparser.stmt.mysql.TLoadDataStmt;
038import gudusoft.gsqlparser.stmt.oracle.TBasicStmt;
039import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreatePackage;
040import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreateTrigger;
041import gudusoft.gsqlparser.stmt.oracle.TPlsqlRecordTypeDefStmt;
042import gudusoft.gsqlparser.stmt.oracle.TPlsqlTableTypeDefStmt;
043import gudusoft.gsqlparser.stmt.redshift.TRedshiftCopy;
044import gudusoft.gsqlparser.stmt.redshift.TRedshiftDeclare;
045import gudusoft.gsqlparser.stmt.snowflake.*;
046import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure;
047import gudusoft.gsqlparser.util.*;
048import gudusoft.gsqlparser.util.json.JSON;
049
050import javax.script.ScriptEngine;
051import javax.script.ScriptEngineManager;
052import javax.script.ScriptException;
053import java.io.*;
054import java.util.*;
055import java.util.concurrent.atomic.AtomicInteger;
056import java.util.regex.Matcher;
057import java.util.regex.Pattern;
058import java.util.stream.Collectors;
059
060import static gudusoft.gsqlparser.EJoinType.right;
061
062@SuppressWarnings("rawtypes")
063public class DataFlowAnalyzer implements IDataFlowAnalyzer {
064
065        private static final Logger logger = LoggerFactory.getLogger(DataFlowAnalyzer.class);
066
067        private static final List<String> TERADATA_BUILTIN_FUNCTIONS = Arrays
068                        .asList(new String[] { "ACCOUNT", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
069                                        "CURRENT_USER", "DATABASE", "DATE", "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", });
070
071        private static final List<String> CONSTANT_BUILTIN_FUNCTIONS = Arrays.asList(new String[] { "ACCOUNT",
072                        "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "DATABASE", "DATE",
073                        "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", "GETDATE" });
074
075        private Stack<TCustomSqlStatement> stmtStack = new Stack<TCustomSqlStatement>();
076        private List<ResultSet> appendResultSets = new ArrayList<ResultSet>();
077        private Set<TCustomSqlStatement> accessedStatements = new HashSet<TCustomSqlStatement>();
078        private Set<TSelectSqlStatement> accessedSubqueries = new HashSet<TSelectSqlStatement>();
079        private Map<String, TCustomSqlStatement> viewDDLMap = new HashMap<String, TCustomSqlStatement>();
080        private Map<String, TCustomSqlStatement> procedureDDLMap = new HashMap<String, TCustomSqlStatement>();
081
082        private SqlInfo[] sqlInfos;
083        private List<ErrorInfo> errorInfos = new ArrayList<ErrorInfo>();
084        private IndexedLinkedHashMap<String, List<SqlInfo>> sqlInfoMap = new IndexedLinkedHashMap<String, List<SqlInfo>>();
085        private TSQLEnv sqlenv = null;
086        private ModelBindingManager modelManager = new ModelBindingManager();
087        private ModelFactory modelFactory = new ModelFactory(modelManager);
088        private List<Long> tableIds = new ArrayList<Long>();
089        private TTableList hiveFromTables;
090        private dataflow dataflow;
091        private String dataflowString;
092        private Option option = new Option();
093
094        {
095                modelManager.TABLE_COLUMN_ID = option.getStartId();
096                modelManager.RELATION_ID = option.getStartId();
097                ModelBindingManager.set(modelManager);
098                ModelBindingManager.setGlobalStmtStack(stmtStack);
099                ModelBindingManager.setGlobalOption(option);
100                ModelBindingManager.setGlobalSqlInfo(sqlInfoMap);
101        }
102
103        public DataFlowAnalyzer(String sqlContent, Option option) {
104                SqlInfo[] sqlInfos = new SqlInfo[1];
105                SqlInfo info = new SqlInfo();
106                info.setSql(sqlContent);
107                info.setOriginIndex(0);
108                sqlInfos[0] = info;
109                this.option = option;
110                ModelBindingManager.setGlobalOption(this.option);
111                this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
112        }
113
114        public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput, String defaultServer,
115                        String defaultDatabase, String defaltSchema) {
116                SqlInfo[] sqlInfos = new SqlInfo[1];
117                SqlInfo info = new SqlInfo();
118                info.setSql(sqlContent);
119                info.setOriginIndex(0);
120                sqlInfos[0] = info;
121                option.setVendor(dbVendor);
122                option.setSimpleOutput(simpleOutput);
123                option.setDefaultServer(defaultServer);
124                option.setDefaultDatabase(defaultDatabase);
125                option.setDefaultSchema(defaltSchema);
126                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
127        }
128
129        public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput) {
130                SqlInfo[] sqlInfos = new SqlInfo[1];
131                SqlInfo info = new SqlInfo();
132                info.setSql(sqlContent);
133                info.setOriginIndex(0);
134                sqlInfos[0] = info;
135                option.setVendor(dbVendor);
136                option.setSimpleOutput(simpleOutput);
137                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
138        }
139
140        public DataFlowAnalyzer(String[] sqlContents, Option option) {
141                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
142                for (int i = 0; i < sqlContents.length; i++) {
143                        SqlInfo info = new SqlInfo();
144                        info.setSql(sqlContents[i]);
145                        info.setOriginIndex(0);
146                        sqlInfos[i] = info;
147                }
148                this.option = option;
149                ModelBindingManager.setGlobalOption(this.option);
150                this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
151        }
152
153        public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput, String defaultServer,
154                        String defaultDatabase, String defaltSchema) {
155                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
156                for (int i = 0; i < sqlContents.length; i++) {
157                        SqlInfo info = new SqlInfo();
158                        info.setSql(sqlContents[i]);
159                        info.setOriginIndex(0);
160                        sqlInfos[i] = info;
161                }
162                option.setVendor(dbVendor);
163                option.setSimpleOutput(simpleOutput);
164                option.setDefaultServer(defaultServer);
165                option.setDefaultDatabase(defaultDatabase);
166                option.setDefaultSchema(defaltSchema);
167                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
168        }
169
170        public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput) {
171                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
172                for (int i = 0; i < sqlContents.length; i++) {
173                        SqlInfo info = new SqlInfo();
174                        info.setSql(sqlContents[i]);
175                        info.setOriginIndex(0);
176                        sqlInfos[i] = info;
177                }
178                option.setVendor(dbVendor);
179                option.setSimpleOutput(simpleOutput);
180                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
181        }
182
183        public DataFlowAnalyzer(SqlInfo[] sqlInfos, Option option) {
184                this.sqlInfos = sqlInfos;
185                this.option = option;
186                ModelBindingManager.setGlobalOption(this.option);
187        }
188
189        public DataFlowAnalyzer(SqlInfo[] sqlInfos, EDbVendor dbVendor, boolean simpleOutput) {
190                this.sqlInfos = sqlInfos;
191                option.setVendor(dbVendor);
192                option.setSimpleOutput(simpleOutput);
193        }
194
195        public DataFlowAnalyzer(File[] sqlFiles, Option option) {
196                SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length];
197                for (int i = 0; i < sqlFiles.length; i++) {
198                        SqlInfo info = new SqlInfo();
199                        info.setSql(SQLUtil.getFileContent(sqlFiles[i]));
200                        info.setFileName(sqlFiles[i].getName());
201                        info.setFilePath(sqlFiles[i].getAbsolutePath());
202                        info.setOriginIndex(0);
203                        sqlInfos[i] = info;
204                }
205                this.sqlInfos = sqlInfos;
206                this.option = option;
207                ModelBindingManager.setGlobalOption(this.option);
208        }
209
210        public DataFlowAnalyzer(File[] sqlFiles, EDbVendor dbVendor, boolean simpleOutput) {
211                SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length];
212                for (int i = 0; i < sqlFiles.length; i++) {
213                        SqlInfo info = new SqlInfo();
214                        info.setSql(SQLUtil.getFileContent(sqlFiles[i]));
215                        info.setFileName(sqlFiles[i].getName());
216                        info.setFilePath(sqlFiles[i].getAbsolutePath());
217                        info.setOriginIndex(0);
218                        sqlInfos[i] = info;
219                }
220                this.sqlInfos = sqlInfos;
221                option.setVendor(dbVendor);
222                option.setSimpleOutput(simpleOutput);
223        }
224
225        public DataFlowAnalyzer(File sqlFile, Option option) {
226                File[] children = SQLUtil.listFiles(sqlFile);
227                SqlInfo[] sqlInfos = new SqlInfo[children.length];
228                for (int i = 0; i < children.length; i++) {
229                        SqlInfo info = new SqlInfo();
230                        info.setSql(SQLUtil.getFileContent(children[i]));
231                        info.setFileName(children[i].getName());
232                        info.setFilePath(children[i].getAbsolutePath());
233                        info.setOriginIndex(0);
234                        sqlInfos[i] = info;
235                }
236                this.sqlInfos = sqlInfos;
237                this.option = option;
238                ModelBindingManager.setGlobalOption(this.option);
239        }
240
241        public DataFlowAnalyzer(File sqlFile, EDbVendor dbVendor, boolean simpleOutput) {
242                File[] children = SQLUtil.listFiles(sqlFile);
243                SqlInfo[] sqlInfos = new SqlInfo[children.length];
244                for (int i = 0; i < children.length; i++) {
245                        SqlInfo info = new SqlInfo();
246                        info.setSql(SQLUtil.getFileContent(children[i]));
247                        info.setFileName(children[i].getName());
248                        info.setFilePath(children[i].getAbsolutePath());
249                        info.setOriginIndex(0);
250                        sqlInfos[i] = info;
251                }
252                this.sqlInfos = sqlInfos;
253                option.setVendor(dbVendor);
254                option.setSimpleOutput(simpleOutput);
255        }
256
257        public boolean isIgnoreRecordSet() {
258                return option.isIgnoreRecordSet();
259        }
260
261        public void setIgnoreRecordSet(boolean ignoreRecordSet) {
262                option.setIgnoreRecordSet(ignoreRecordSet);
263        }
264
265        public boolean isSimpleShowTopSelectResultSet() {
266                return option.isSimpleShowTopSelectResultSet();
267        }
268
269        public void setSimpleShowTopSelectResultSet(boolean simpleShowTopSelectResultSet) {
270                option.setSimpleShowTopSelectResultSet(simpleShowTopSelectResultSet);
271        }
272
273        public boolean isSimpleShowFunction() {
274                return option.isSimpleShowFunction();
275        }
276
277        public void setSimpleShowFunction(boolean simpleShowFunction) {
278                option.setSimpleShowFunction(simpleShowFunction);
279        }
280
281        public boolean isShowJoin() {
282                return option.isShowJoin();
283        }
284
285        public void setShowJoin(boolean showJoin) {
286                option.setShowJoin(showJoin);
287        }
288
289        public void setShowCallRelation(boolean showCallRelation) {
290                option.setShowCallRelation(showCallRelation);
291        }
292
293        public boolean isShowCallRelation() {
294                return option.isShowCallRelation();
295        }
296
297        public boolean isShowImplicitSchema() {
298                return option.isShowImplicitSchema();
299        }
300
301        public void setShowImplicitSchema(boolean showImplicitSchema) {
302                option.setShowImplicitSchema(showImplicitSchema);
303        }
304
305        public boolean isShowConstantTable() {
306                return option.isShowConstantTable();
307        }
308
309        public void setShowConstantTable(boolean showConstantTable) {
310                option.setShowConstantTable(showConstantTable);
311        }
312
313        public boolean isShowCountTableColumn() {
314                return option.isShowCountTableColumn();
315        }
316
317        public void setShowCountTableColumn(boolean showCountTableColumn) {
318                option.setShowCountTableColumn(showCountTableColumn);
319        }
320
321        public boolean isTransform() {
322                return option.isTransform();
323        }
324
325        public void setTransform(boolean transform) {
326                option.setTransform(transform);
327                if (option.isTransformCoordinate()) {
328                        option.setTransform(true);
329                }
330        }
331
332        public boolean isTransformCoordinate() {
333                return option.isTransformCoordinate();
334        }
335
336        public void setTransformCoordinate(boolean transformCoordinate) {
337                option.setTransformCoordinate(transformCoordinate);
338                if (transformCoordinate) {
339                        option.setTransform(true);
340                }
341        }
342
343        public boolean isLinkOrphanColumnToFirstTable() {
344                return option.isLinkOrphanColumnToFirstTable();
345        }
346
347        public void setLinkOrphanColumnToFirstTable(boolean linkOrphanColumnToFirstTable) {
348                option.setLinkOrphanColumnToFirstTable(linkOrphanColumnToFirstTable);
349        }
350
351        public boolean isIgnoreTemporaryTable() {
352                return option.isIgnoreTemporaryTable();
353        }
354
355        public void setIgnoreTemporaryTable(boolean ignoreTemporaryTable) {
356                option.setIgnoreTemporaryTable(ignoreTemporaryTable);
357        }
358        
359        public boolean isIgnoreCoordinate() {
360                return option.isIgnoreCoordinate();
361        }
362
363        public void setIgnoreCoordinate(boolean ignoreCoordinate) {
364                option.setIgnoreCoordinate(ignoreCoordinate);
365        }
366
367        public void setHandleListener(DataFlowHandleListener listener) {
368                option.setHandleListener(listener);
369        }
370
371        public void setSqlEnv(TSQLEnv sqlenv) {
372                this.sqlenv = sqlenv;
373        }
374
375        public void setOption(Option option) {
376                this.option = option;
377                ModelBindingManager.setGlobalOption(this.option);
378        }
379
380        public Option getOption() {
381                return option;
382        }
383
384        public synchronized String chechSyntax() {
385                StringBuilder builder = new StringBuilder();
386                if (sqlInfos != null) {
387                        for (SqlInfo sqlInfo : sqlInfos) {
388                                String content = sqlInfo.getSql();
389                                if (content != null && content.indexOf("<dlineage") != -1) {
390                                        try {
391                                                XML2Model.loadXML(dataflow.class, content);
392                                                continue;
393                                        } catch (Exception e) {
394                                                builder.append("Parsing dataflow ").append("occurs errors.\n").append(e.getMessage())
395                                                                .append("\n");
396                                        }
397                                }
398                                if (content != null && content.trim().startsWith("{")) {
399                                        Map queryObject = (Map) JSON.parseObject(content);
400                                        content = (String) queryObject.get("sourceCode");
401                                }
402                                if (MetadataReader.isMetadata(content)) {
403                                        continue;
404                                }
405                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
406                                sqlparser.sqltext = content;
407                                int result = sqlparser.parse();
408                                if (result != 0) {
409                                        builder.append("Parsing sql ").append("occurs errors.\n").append(sqlparser.getErrormessage())
410                                                        .append("\n");
411                                }
412                        }
413                }
414                return builder.toString();
415        }
416
417        public synchronized String generateDataFlow(boolean withExtraInfo) {
418                if (ModelBindingManager.get() == null) {
419                        ModelBindingManager.set(modelManager);
420                }
421
422                dataflow = analyzeSqlScript();
423
424                if (dataflow != null && !withExtraInfo && dataflow.getResultsets() != null) {
425                        for (table t : dataflow.getResultsets()) {
426                                t.setIsTarget(null);
427                                if (t.getColumns() != null) {
428                                        for (column t1 : t.getColumns()) {
429                                                t1.setIsFunction(null);
430                                        }
431                                }
432                        }
433                }
434                
435                if(dataflow!=null && dataflow.getRelationships()!=null && option.getFilterRelationTypes()!=null && !option.getFilterRelationTypes().isEmpty()) {
436                        List<relationship> relationships = new ArrayList<relationship>();
437                        for(relationship relationship: dataflow.getRelationships()) {
438                                if(option.getFilterRelationTypes().contains(relationship.getType())) {
439                                        relationships.add(relationship);
440                                }
441                        }
442                        dataflow.setRelationships(relationships);
443                }
444
445                if (option.getHandleListener() != null) {
446                        option.getHandleListener().endAnalyze();
447                        option.getHandleListener().startOutputDataFlowXML();
448                }
449                
450                if (option.isOutput()) {
451                        if (dataflow != null) {
452                                if (option.isTextFormat()) {
453                                        dataflowString = getTextOutput(dataflow);
454                                } else {
455                                        try {
456                                                dataflowString = XML2Model.saveXML(dataflow);
457                                        }catch (Exception e){
458                                                logger.error("Output dataflow to xml failed.", e);
459                                                dataflowString = null;
460                                        }
461                                }
462                        }
463                }
464
465                if (option.getHandleListener() != null) {
466                        option.getHandleListener().endOutputDataFlowXML(dataflowString == null ? 0 : dataflowString.length());
467                }
468
469                return dataflowString;
470        }
471
472        private dataflow removeDuplicateColumns(dataflow dataflow) {
473                List<table> tables = new ArrayList<table>();
474                if (dataflow.getTables() != null) {
475                        tables.addAll(dataflow.getTables());
476                }
477                if (dataflow.getViews() != null) {
478                        tables.addAll(dataflow.getViews());
479                }
480                if (dataflow.getStages() != null) {
481                        tables.addAll(dataflow.getStages());
482                }
483                if (dataflow.getDatasources() != null) {
484                        tables.addAll(dataflow.getDatasources());
485                }
486                if (dataflow.getStreams() != null) {
487                        tables.addAll(dataflow.getStreams());
488                }
489                if (dataflow.getPaths() != null) {
490                        tables.addAll(dataflow.getPaths());
491                }
492                if (dataflow.getVariables() != null) {
493                        tables.addAll(dataflow.getVariables());
494                }
495                if (dataflow.getResultsets() != null) {
496                        tables.addAll(dataflow.getResultsets());
497                }
498                for (table table : tables) {
499                        if (table.getColumns() == null) {
500                                continue;
501                        }
502                        Set<String> columnIds = new HashSet<String>();
503                        Iterator<column> iter = table.getColumns().iterator();
504                        while(iter.hasNext()) {
505                                column column = iter.next();
506                                String id = column.getId();
507                                if (columnIds.contains(id)) {
508                                        iter.remove();
509                                } else {
510                                        columnIds.add(id);
511                                }
512                        }
513                }
514                return dataflow;
515        }
516
517        public synchronized String generateDataFlow() {
518                return generateDataFlow(false);
519        }
520
521        public synchronized String generateSqlInfos() {
522                return JSON.toJSONString(sqlInfoMap);
523        }
524
525        public Map<String, List<SqlInfo>> getSqlInfos() {
526                return sqlInfoMap;
527        }
528
529        public Map getHashSQLMap() {
530                return modelManager.getHashSQLMap();
531        }
532        
533        public Map getDynamicSQLMap() {
534                return modelManager.getDynamicSQLMap();
535        }
536
537        /**
538         * @deprecated please use SqlInfoHelper.getSelectedDbObjectInfo
539         */
540        public DbObjectPosition getSelectedDbObjectInfo(Coordinate start, Coordinate end) {
541                if (start == null || end == null) {
542                        throw new IllegalArgumentException("Coordinate can't be null.");
543                }
544
545                String hashCode = start.getHashCode();
546
547                if (hashCode == null) {
548                        throw new IllegalArgumentException("Coordinate hashcode can't be null.");
549                }
550
551                int dbObjectStartLine = (int) start.getX() - 1;
552                int dbObjectStarColumn = (int) start.getY() - 1;
553                int dbObjectEndLine = (int) end.getX() - 1;
554                int dbObjectEndColumn = (int) end.getY() - 1;
555                List<SqlInfo> sqlInfoList;
556                if (hashCode.matches("\\d+")) {
557                        sqlInfoList = sqlInfoMap.getValueAtIndex(Integer.valueOf(hashCode));
558                } else {
559                        sqlInfoList = sqlInfoMap.get(hashCode);
560                }
561                for (int j = 0; j < sqlInfoList.size(); j++) {
562                        SqlInfo sqlInfo = sqlInfoList.get(j);
563                        int startLine = sqlInfo.getLineStart();
564                        int endLine = sqlInfo.getLineEnd();
565                        if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) {
566                                DbObjectPosition position = new DbObjectPosition();
567                                position.setFile(sqlInfo.getFileName());
568                                position.setFilePath(sqlInfo.getFilePath());
569                                position.setSql(sqlInfo.getSql());
570                                position.setIndex(sqlInfo.getOriginIndex());
571                                List<Pair<Integer, Integer>> positions = position.getPositions();
572                                positions.add(new Pair<Integer, Integer>(
573                                                dbObjectStartLine - startLine + sqlInfo.getOriginLineStart() + 1, dbObjectStarColumn + 1));
574                                positions.add(new Pair<Integer, Integer>(dbObjectEndLine - startLine + sqlInfo.getOriginLineStart() + 1,
575                                                dbObjectEndColumn + 1));
576                                return position;
577                        }
578                }
579                return null;
580        }
581
582        public static dataflow mergeTables(dataflow dataflow, Long startId) {
583                return mergeTables(dataflow, startId, new Option());
584        }
585
586        public static dataflow mergeTables(dataflow dataflow, Long startId, Option option) {
587                List<table> tableCopy = new ArrayList<table>();
588                List<table> viewCopy = new ArrayList<table>();
589                List<table> databaseCopy = new ArrayList<table>();
590                List<table> schemaCopy = new ArrayList<table>();
591                List<table> stageCopy = new ArrayList<table>();
592                List<table> dataSourceCopy = new ArrayList<table>();
593                List<table> streamCopy = new ArrayList<table>();
594                List<table> fileCopy = new ArrayList<table>();
595                List<table> variableCopy = new ArrayList<table>();
596                List<table> cursorCopy = new ArrayList<table>();
597                List<table> resultSetCopy = new ArrayList<table>();
598                if (dataflow.getTables() != null) {
599                        tableCopy.addAll(dataflow.getTables());
600                }
601                dataflow.setTables(tableCopy);
602                if (dataflow.getViews() != null) {
603                        viewCopy.addAll(dataflow.getViews());
604                }
605                dataflow.setViews(viewCopy);
606                if (dataflow.getDatabases() != null) {
607                        databaseCopy.addAll(dataflow.getDatabases());
608                }
609                dataflow.setDatabases(databaseCopy);
610                if (dataflow.getSchemas() != null) {
611                        schemaCopy.addAll(dataflow.getSchemas());
612                }
613                dataflow.setSchemas(schemaCopy);
614                if (dataflow.getStages() != null) {
615                        stageCopy.addAll(dataflow.getStages());
616                }
617                dataflow.setStages(stageCopy);
618                if (dataflow.getDatasources() != null) {
619                        dataSourceCopy.addAll(dataflow.getDatasources());
620                }
621                dataflow.setDatasources(dataSourceCopy);
622                if (dataflow.getStreams() != null) {
623                        streamCopy.addAll(dataflow.getStreams());
624                }
625                dataflow.setStreams(streamCopy);
626                if (dataflow.getPaths() != null) {
627                        fileCopy.addAll(dataflow.getPaths());
628                }
629                dataflow.setPaths(fileCopy);
630                if (dataflow.getVariables() != null) {
631                        variableCopy.addAll(dataflow.getVariables());
632                }
633                dataflow.setVariables(variableCopy);
634                if (dataflow.getResultsets() != null) {
635                        resultSetCopy.addAll(dataflow.getResultsets());
636                }
637                dataflow.setResultsets(resultSetCopy);
638
639                Map<String, List<table>> tableMap = new HashMap<String, List<table>>();
640                Map<String, String> tableTypeMap = new HashMap<String, String>();
641                Map<String, TMssqlCreateType> mssqlTypeMap = new HashMap<String, TMssqlCreateType>();
642                Map<String, String> tableIdMap = new HashMap<String, String>();
643
644                Map<String, List<column>> columnMap = new HashMap<String, List<column>>();
645                Map<String, Set<String>> tableColumnMap = new HashMap<String, Set<String>>();
646                Map<String, String> columnIdMap = new HashMap<String, String>();
647                Map<String, column> columnMergeIdMap = new HashMap<String, column>();
648
649                List<table> tables = new ArrayList<table>();
650                tables.addAll(dataflow.getTables());
651                tables.addAll(dataflow.getViews());
652                tables.addAll(dataflow.getDatabases());
653                tables.addAll(dataflow.getSchemas());
654                tables.addAll(dataflow.getStages());
655                tables.addAll(dataflow.getDatasources());
656                tables.addAll(dataflow.getStreams());
657                tables.addAll(dataflow.getPaths());
658                tables.addAll(dataflow.getResultsets());
659                tables.addAll(dataflow.getVariables());
660                
661                Set<String> columnIds = new HashSet<String>();
662
663                for (table table : tables) {
664                        String qualifiedTableName = DlineageUtil.getQualifiedTableName(table);
665                        String tableFullName = DlineageUtil.getIdentifierNormalTableName(qualifiedTableName);
666
667                        if (!tableMap.containsKey(tableFullName)) {
668                                tableMap.put(tableFullName, new ArrayList<table>());
669                        }
670
671                        tableMap.get(tableFullName).add(table);
672
673                        if (!tableTypeMap.containsKey(tableFullName)) {
674                                tableTypeMap.put(tableFullName, table.getType());
675                        } else if ("view".equals(table.getSubType())) {
676                                tableTypeMap.put(tableFullName, table.getType());
677                        } else if ("database".equals(table.getSubType())) {
678                                tableTypeMap.put(tableFullName, table.getType());
679                        } else if ("schema".equals(table.getSubType())) {
680                                tableTypeMap.put(tableFullName, table.getType());
681                        } else if ("stage".equals(table.getSubType())) {
682                                tableTypeMap.put(tableFullName, table.getType());
683                        } else if ("sequence".equals(table.getSubType())) {
684                                tableTypeMap.put(tableFullName, table.getType());
685                        } else if ("datasource".equals(table.getSubType())) {
686                                tableTypeMap.put(tableFullName, table.getType());
687                        } else if ("stream".equals(table.getSubType())) {
688                                tableTypeMap.put(tableFullName, table.getType());
689                        } else if ("file".equals(table.getSubType())) {
690                                tableTypeMap.put(tableFullName, table.getType());
691                        } else if ("table".equals(tableTypeMap.get(tableFullName))) {
692                                tableTypeMap.put(tableFullName, table.getType());
693                        } else if ("variable".equals(tableTypeMap.get(tableFullName))) {
694                                tableTypeMap.put(tableFullName, table.getType());
695                        }
696
697                        if (table.getColumns() != null) {
698                                if (!tableColumnMap.containsKey(tableFullName)) {
699                                        tableColumnMap.put(tableFullName, new LinkedHashSet<String>());
700                                }
701                                for (column column : table.getColumns()) {
702                                        String columnFullName = tableFullName + "."
703                                                        + (column.getQualifiedTable() != null
704                                                                        ? (DlineageUtil.getIdentifierNormalTableName(column.getQualifiedTable()) + ".")
705                                                                        : "")
706                                                        + ("false".equals(table.getIsTarget()) ? DlineageUtil.normalizeColumnName(column.getName())
707                                                                        : DlineageUtil.getIdentifierNormalColumnName(column.getName()));
708
709                                        if (!columnMap.containsKey(columnFullName)) {
710                                                columnMap.put(columnFullName, new ArrayList<column>());
711                                                tableColumnMap.get(tableFullName).add(columnFullName);
712                                        }
713
714                                        columnMap.get(columnFullName).add(column);
715                                        columnIds.add(column.getId());
716                                }
717                        }
718                }
719
720                Iterator<String> tableNameIter = tableMap.keySet().iterator();
721                while (tableNameIter.hasNext()) {
722                        String tableName = tableNameIter.next();
723                        List<table> tableList = tableMap.get(tableName);
724                        table table;
725                        if (tableList.size() > 1) {
726                                table standardTable = tableList.get(0);
727                                // Function允许重名,不做合并处理
728                                if (standardTable.isFunction()) {
729                                        continue;
730                                }
731                                
732                                // Variable允许重名,不做合并处理
733                                if (standardTable.isVariable()) {
734                                        continue;
735                                }
736                                
737                                // 临时表不做合并处理
738                                if(SQLUtil.isTempTable(standardTable)) {
739                                        continue;
740                                }
741
742                                String type = tableTypeMap.get(tableName);
743                                table = new table();
744                                table.setId(String.valueOf(++startId));
745                                table.setServer(standardTable.getServer());
746                                table.setDatabase(standardTable.getDatabase());
747                                table.setSchema(standardTable.getSchema());
748                                table.setName(standardTable.getName());
749                                table.setDisplayName(standardTable.getDisplayName());
750                                table.setParent(standardTable.getParent());
751                                table.setMore(standardTable.getMore());
752                                table.setColumns(new ArrayList<column>());
753                                table.setSubType(standardTable.getSubType());
754                                Set<String> processIds = new LinkedHashSet<String>();
755                                for (int k = 0; k < tableList.size(); k++) {
756                                        if (tableList.get(k).getProcessIds() != null) {
757                                                processIds.addAll(tableList.get(k).getProcessIds());
758                                        }
759                                }
760                                if (!processIds.isEmpty()) {
761                                        table.setProcessIds(new ArrayList<String>(processIds));
762                                }
763                                Set<String> alias = new LinkedHashSet<String>();
764                                for (int k = 0; k < tableList.size(); k++) {
765                                        if (tableList.get(k).getAlias() != null) {
766                                                alias.addAll(Arrays.asList(tableList.get(k).getAlias().split("\\s*,\\s*")));
767                                        }
768                                }
769                                if (!alias.isEmpty()) {
770                                        String aliasString = Arrays.toString(alias.toArray(new String[0]));
771                                        table.setAlias(aliasString.substring(1, aliasString.length() - 1));
772                                }
773                                table.setType(type);
774                                for (table item : tableList) {
775                                        if (!SQLUtil.isEmpty(table.getCoordinate()) && !SQLUtil.isEmpty(item.getCoordinate())) {
776                                                if (table.getCoordinate().indexOf(item.getCoordinate()) == -1) {
777                                                        table.appendCoordinate(item.getCoordinate());
778                                                }
779                                        } else if (!SQLUtil.isEmpty(item.getCoordinate())) {
780                                                table.setCoordinate(item.getCoordinate());
781                                        }
782
783                                        if (item.getStarStmt() != null) {
784                                                table.setStarStmt(item.getStarStmt());
785                                        }
786
787                                        tableIdMap.put(item.getId(), table.getId());
788
789                                        if (item.isView()) {
790                                                dataflow.getViews().remove(item);
791                                        } else if (item.isDatabaseType()) {
792                                                dataflow.getDatabases().remove(item);
793                                        } else if (item.isSchemaType()) {
794                                                dataflow.getSchemas().remove(item);
795                                        } else if (item.isStage()) {
796                                                dataflow.getStages().remove(item);
797                                        } else if (item.isDataSource()) {
798                                                dataflow.getDatasources().remove(item);
799                                        } else if (item.isStream()) {
800                                                dataflow.getStreams().remove(item);
801                                        } else if (item.isFile()) {
802                                                dataflow.getPaths().remove(item);
803                                        } else if (item.isVariable()) {
804                                                dataflow.getVariables().remove(item);
805                                        } else if (item.isTable()) {
806                                                dataflow.getTables().remove(item);
807                                        } else if (item.isResultSet()) {
808                                                dataflow.getResultsets().remove(item);
809                                        }
810                                }
811
812                                if (table.isView()) {
813                                        dataflow.getViews().add(table);
814                                } else if (table.isDatabaseType()) {
815                                        dataflow.getDatabases().add(table);
816                                } else if (table.isSchemaType()) {
817                                        dataflow.getSchemas().add(table);
818                                } else if (table.isStage()) {
819                                        dataflow.getStages().add(table);
820                                } else if (table.isDataSource()) {
821                                        dataflow.getDatasources().add(table);
822                                } else if (table.isStream()) {
823                                        dataflow.getStreams().add(table);
824                                } else if (table.isFile()) {
825                                        dataflow.getPaths().add(table);
826                                } else if (table.isVariable()) {
827                                        dataflow.getVariables().add(table);
828                                } else if (table.isResultSet()) {
829                                        dataflow.getResultsets().add(table);
830                                } else {
831                                        dataflow.getTables().add(table);
832                                }
833                        } else {
834                                table = tableList.get(0);
835                                if(Boolean.TRUE.toString().equals(table.getIsDetermined())){
836                                        continue;
837                                }
838                                
839                                if (option.isIgnoreUnusedSynonym() && SubType.synonym.name().equals(table.getSubType())) {
840                                        dataflow.getTables().remove(table);
841                                        tableColumnMap.get(tableName).clear();
842                                        continue;
843                                }
844                        }
845
846                        Set<String> columns = tableColumnMap.get(tableName);
847                        Iterator<String> columnIter = columns.iterator();
848                        List<column> mergeColumns = new ArrayList<column>();
849                        while (columnIter.hasNext()) {
850                                String columnName = columnIter.next();
851                                List<column> columnList = columnMap.get(columnName);
852                                List<column> functions = new ArrayList<column>();
853                                for (column t : columnList) {
854                                        if (Boolean.TRUE.toString().equals(t.getIsFunction())) {
855                                                functions.add(t);
856                                        }
857                                }
858                                if (functions != null && !functions.isEmpty()) {
859                                        for (column function : functions) {
860                                                mergeColumns.add(function);
861                                                columnIdMap.put(function.getId(), function.getId());
862                                                columnMergeIdMap.put(function.getId(), function);
863                                        }
864
865                                        columnList.removeAll(functions);
866                                }
867                                if (!columnList.isEmpty()) {
868                                        column firstColumn = columnList.iterator().next();
869                                        if (columnList.size() > 1) {
870                                                column mergeColumn = new column();
871                                                mergeColumn.setId(String.valueOf(++startId));
872                                                mergeColumn.setName(firstColumn.getName());
873                                                mergeColumn.setDisplayName(firstColumn.getDisplayName());
874                                                mergeColumn.setSource(firstColumn.getSource());
875                                                mergeColumn.setQualifiedTable(firstColumn.getQualifiedTable());
876                                                mergeColumn.setDataType(firstColumn.getDataType());
877                                                mergeColumn.setForeignKey(firstColumn.isForeignKey());
878                                                mergeColumn.setPrimaryKey(firstColumn.isPrimaryKey());
879                                                mergeColumn.setUnqiueKey(firstColumn.isUnqiueKey());
880                                                mergeColumn.setIndexKey(firstColumn.isIndexKey());
881                                                mergeColumns.add(mergeColumn);
882                                                for (column item : columnList) {
883                                                        mergeColumn.appendCoordinate(item.getCoordinate());
884                                                        columnIdMap.put(item.getId(), mergeColumn.getId());
885                                                }
886                                                columnMergeIdMap.put(mergeColumn.getId(), mergeColumn);
887                                                columnIds.add(mergeColumn.getId());
888                                        } else {
889                                                mergeColumns.add(firstColumn);
890                                                columnIdMap.put(firstColumn.getId(), firstColumn.getId());
891                                                columnMergeIdMap.put(firstColumn.getId(), firstColumn);
892                                        }
893                                }
894                        }
895                        table.setColumns(mergeColumns);
896                }
897
898                if (dataflow.getRelationships() != null) {
899                        Map<String, relationship> mergeRelations = new LinkedHashMap<String, relationship>();
900                        for (int i = 0; i < dataflow.getRelationships().size(); i++) {
901                                relationship relation = dataflow.getRelationships().get(i);
902                                
903                                if("crud".equals(relation.getType()) && option.getAnalyzeMode() == AnalyzeMode.crud) {
904                                        String jsonString = JSON.toJSONString(relation).replaceAll("\"id\":\".+?\"", "");
905                                        String key = SHA256.getMd5(jsonString);
906                                        if (!mergeRelations.containsKey(key)) {
907                                                mergeRelations.put(key, relation);
908                                        }
909                                        continue;
910                                }
911                                
912                                targetColumn target = relation.getTarget();
913                                if ("call".equals(relation.getType())) {
914                                        target = relation.getCaller();
915                                }
916                                if (target != null && tableIdMap.containsKey(target.getParent_id())) {
917                                        target.setParent_id(tableIdMap.get(target.getParent_id()));
918                                }
919
920                                if (columnIdMap.containsKey(target.getId())) {
921                                        target.setId(columnIdMap.get(target.getId()));
922                                        target.setCoordinate(columnMergeIdMap.get(target.getId()).getCoordinate());
923                                }
924                                else if(option.isIgnoreUnusedSynonym() && EffectType.synonym.name().equals(relation.getEffectType())){
925                                        continue;
926                                }
927                                
928                                if (!"call".equals(relation.getType()) && !columnIds.contains(target.getId())) {
929                                        continue;
930                                }
931
932                                List<sourceColumn> sources = relation.getSources();
933                                if ("call".equals(relation.getType())) {
934                                        sources = relation.getCallees();
935                                }
936                                Set<sourceColumn> sourceSet = new LinkedHashSet<sourceColumn>();
937                                if (sources != null) {
938                                        for (sourceColumn source : sources) {
939                                                if (!"call".equals(relation.getType()) && !columnIds.contains(source.getId())) {
940                                                        continue;
941                                                }
942                                                if (tableIdMap.containsKey(source.getParent_id())) {
943                                                        source.setParent_id(tableIdMap.get(source.getParent_id()));
944                                                }
945                                                if (tableIdMap.containsKey(source.getSource_id())) {
946                                                        source.setSource_id(tableIdMap.get(source.getSource_id()));
947                                                }
948                                                if (columnIdMap.containsKey(source.getId())) {
949                                                        source.setId(columnIdMap.get(source.getId()));
950                                                        source.setCoordinate(columnMergeIdMap.get(source.getId()).getCoordinate());
951                                                }
952                                        }
953
954                                        sourceSet.addAll(sources);
955                                        if ("call".equals(relation.getType())) {
956                                                relation.setCallees(new ArrayList<sourceColumn>(sourceSet));
957                                        } else {
958                                                relation.setSources(new ArrayList<sourceColumn>(sourceSet));
959                                        }
960                                }
961
962                                String jsonString = JSON.toJSONString(relation).replaceAll("\"id\":\".+?\"", "");
963                                String key = SHA256.getMd5(jsonString);
964                                if (!mergeRelations.containsKey(key)) {
965                                        mergeRelations.put(key, relation);
966                                }
967                        }
968
969                        dataflow.setRelationships(new ArrayList<relationship>(mergeRelations.values()));
970                }
971
972                tableMap.clear();
973                tableTypeMap.clear();
974                tableIdMap.clear();
975                columnMap.clear();
976                tableColumnMap.clear();
977                columnIdMap.clear();
978                columnMergeIdMap.clear();
979                tables.clear();
980                return dataflow;
981        }
982
983        public synchronized dataflow getDataFlow() {
984                if (dataflow != null) {
985                        return dataflow;
986                } else if (dataflowString != null) {
987                        return XML2Model.loadXML(dataflow.class, dataflowString);
988                }
989                return null;
990        }
991
992        List<ErrorInfo> metadataErrors = new ArrayList<>();
993        
994        private synchronized dataflow analyzeSqlScript() {
995                init();
996
997                try {
998                        dataflow dataflow = new dataflow();
999                        
1000                        if (sqlInfos != null) {
1001                                if (option.getHandleListener() != null) {
1002                                        if (sqlInfos.length == 1) {
1003                                                option.getHandleListener().startAnalyze(null, sqlInfos[0].getSql().length(), false);
1004                                        } else {
1005                                                option.getHandleListener().startAnalyze(null, sqlInfos.length, true);
1006                                        }
1007                                }
1008
1009                                if (sqlenv == null) {
1010                                        if (option.getHandleListener() != null) {
1011                                                option.getHandleListener().startParseSQLEnv();
1012                                        }
1013                                        TSQLEnv[] sqlenvs = new SQLEnvParser(option.getDefaultServer(), option.getDefaultDatabase(),
1014                                                        option.getDefaultSchema()).parseSQLEnv(option.getVendor(), sqlInfos);
1015                                        if (sqlenvs != null && sqlenvs.length > 0) {
1016                                                sqlenv = sqlenvs[0];
1017                                        }
1018                                        if (option.getHandleListener() != null) {
1019                                                option.getHandleListener().endParseSQLEnv();
1020                                        }
1021                                }
1022                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
1023                                Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap = new LinkedHashMap<String, Pair3<StringBuilder, AtomicInteger, String>>();
1024                                for (int i = 0; i < sqlInfos.length; i++) {
1025                                        SqlInfo sqlInfo = sqlInfos[i];
1026                                        if (sqlInfo == null) {
1027                                                sqlInfoMap.put(String.valueOf(i), new ArrayList<SqlInfo>());
1028                                                continue;
1029                                        }
1030                                        String sql = sqlInfo.getSql();
1031                                        if(sql!=null && sql.trim().startsWith("<") && sql.indexOf("<dlineage")!=-1){
1032                                                dataflow temp = XML2Model.loadXML(dataflow.class, sql);
1033                                                if(sqlInfos.length == 1){
1034                                                        dataflow = temp;
1035                                                }
1036                                                else {
1037                                                        if (temp.getTables() != null) {
1038                                                                dataflow.getTables().addAll(temp.getTables());
1039                                                        }
1040                                                        if (temp.getViews() != null) {
1041                                                                dataflow.getViews().addAll(temp.getViews());
1042                                                        }
1043                                                        if (temp.getResultsets() != null) {
1044                                                                dataflow.getResultsets().addAll(temp.getResultsets());
1045                                                        }
1046                                                        if (temp.getRelationships() != null) {
1047                                                                dataflow.getRelationships().addAll(temp.getRelationships());
1048                                                        }
1049                                                        if (temp.getErrors() != null) {
1050                                                                dataflow.getErrors().addAll(temp.getErrors());
1051                                                        }
1052                                                }
1053                                        }
1054                                        else if (sql != null && sql.trim().startsWith("{")) {
1055                                                EDbVendor vendor = SQLUtil.isEmpty(sqlInfo.getDbVendor()) ? option.getVendor()
1056                                                                : EDbVendor.valueOf(sqlInfo.getDbVendor());
1057                                                TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(),
1058                                                                option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql);
1059                                                if (sqlenvs != null && sqlenvs.length > 0) {
1060                                                        if (sqlenv == null) {
1061                                                                sqlenv = sqlenvs[0];
1062                                                        } else {
1063                                                                sqlenv = SQLEnvParser.mergeSQLEnv(Arrays.asList(sqlenv, sqlenvs[0]));
1064                                                        }
1065                                                }
1066                                                if (sqlenv != null) {
1067                                                        if (MetadataReader.isGrabit(sql) || MetadataReader.isSqlflow(sql)) {
1068                                                                String hash = SHA256.getMd5(sql);
1069                                                                String fileHash = SHA256.getMd5(hash);
1070                                                                if (!sqlInfoMap.containsKey(fileHash)) {
1071                                                                        sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1072                                                                        sqlInfoMap.get(fileHash).add(sqlInfo);
1073                                                                }
1074                                                                ModelBindingManager.setGlobalHash(fileHash);
1075                                                                dataflow temp = null;
1076
1077                                                                if (MetadataReader.isGrabit(sql)) {
1078                                                                        temp = new GrabitMetadataAnalyzer().analyzeMetadata(option.getVendor(), sql);
1079                                                                } else {
1080                                                                        temp = new SqlflowMetadataAnalyzer(sqlenv).analyzeMetadata(option.getVendor(), sql);
1081                                                                }
1082//                                                              if (temp.getPackages() != null) {
1083//                                                                      dataflow.getPackages().addAll(temp.getPackages());
1084//                                                              }
1085//                                                              if (temp.getProcedures() != null) {
1086//                                                                      dataflow.getProcedures().addAll(temp.getProcedures());
1087//                                                              }
1088                                                                if (temp.getTables() != null) {
1089                                                                        dataflow.getTables().addAll(temp.getTables());
1090                                                                }
1091                                                                if (temp.getViews() != null) {
1092                                                                        dataflow.getViews().addAll(temp.getViews());
1093                                                                }
1094                                                                if (temp.getResultsets() != null) {
1095                                                                        dataflow.getResultsets().addAll(temp.getResultsets());
1096                                                                }
1097                                                                if (temp.getRelationships() != null) {
1098                                                                        dataflow.getRelationships().addAll(temp.getRelationships());
1099                                                                }
1100                                                                if (temp.getErrors() != null) {
1101                                                                        dataflow.getErrors().addAll(temp.getErrors());
1102                                                                }
1103                                                                if (sql.indexOf("createdBy") != -1) {
1104                                                                        if (sql.toLowerCase().indexOf("sqldep") != -1
1105                                                                                        || sql.toLowerCase().indexOf("grabit") != -1) {
1106                                                                                Map jsonObject = (Map) JSON.parseObject(sql);
1107                                                                                List<Map> queries = (List<Map>) jsonObject.get("queries");
1108                                                                                if (queries != null) {
1109                                                                                        for (int j = 0; j < queries.size(); j++) {
1110                                                                                                Map queryObject = queries.get(j);
1111                                                                                                appendSqlInfo(databaseMap, j, sqlInfo, queryObject);
1112                                                                                        }
1113                                                                                }
1114                                                                        } else if (sql.toLowerCase().indexOf("sqlflow") != -1) {
1115                                                                                Map sqlflow = (Map) JSON.parseObject(sql);
1116                                                                                List<Map> servers = (List<Map>) sqlflow.get("servers");
1117                                                                                if (servers != null) {
1118                                                                                        for (Map serverObject : servers) {
1119                                                                                                List<Map> queries = (List<Map>) serverObject.get("queries");
1120                                                                                                if (queries != null) {
1121                                                                                                        for (int j = 0; j < queries.size(); j++) {
1122                                                                                                                Map queryObject = queries.get(j);
1123                                                                                                                appendSqlInfo(databaseMap, j, sqlInfo, queryObject);
1124                                                                                                        }
1125                                                                                                }
1126                                                                                        }
1127                                                                                }
1128                                                                                List<Map> errorMessages =  (List<Map>) sqlflow.get("errorMessages");
1129                                                                                if(errorMessages!=null && !errorMessages.isEmpty()) {
1130                                                                                        for(Map error: errorMessages){
1131                                                                                                ErrorInfo errorInfo = new ErrorInfo();
1132                                                                                                errorInfo.setErrorType(ErrorInfo.METADATA_ERROR);
1133                                                                                                errorInfo.setErrorMessage((String)error.get("errorMessage"));
1134                                                                                                errorInfo.setFileName(sqlInfo.getFileName());
1135                                                                                                errorInfo.setFilePath(sqlInfo.getFilePath());
1136                                                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L,
1137                                                                                                                ModelBindingManager.getGlobalHash()));
1138                                                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L,
1139                                                                                                                ModelBindingManager.getGlobalHash()));
1140                                                                                                errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L));
1141                                                                                                errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L));
1142                                                                                                metadataErrors.add(errorInfo);
1143                                                                                        }
1144                                                                                }
1145                                                                        }
1146                                                                }
1147                                                        } else {
1148                                                                Map queryObject = (Map) JSON.parseObject(sql);
1149                                                                appendSqlInfo(databaseMap, i, sqlInfo, queryObject);
1150                                                        }
1151                                                } else {
1152                                                        Map queryObject = (Map) JSON.parseObject(sql);
1153                                                        appendSqlInfo(databaseMap, i, sqlInfo, queryObject);
1154                                                }
1155                                        } else {
1156                                                ModelBindingManager.removeGlobalDatabase();
1157                                                ModelBindingManager.removeGlobalSchema();
1158                                                ModelBindingManager.removeGlobalHash();
1159
1160                                                String content = sql;
1161
1162                                                if (content == null) {
1163                                                        continue;
1164                                                }
1165
1166                                                TGSqlParser parser = new TGSqlParser(option.getVendor());
1167                                                String delimiterChar = String.valueOf(parser.getFlexer().delimiterchar);
1168
1169                                                if (sqlInfos.length > 1) {
1170                                                        if (content.trim().endsWith(delimiterChar) || content.trim().endsWith(";")) {
1171                                                                content += "\n";
1172                                                        } else if (option.getVendor() == EDbVendor.dbvredshift
1173                                                                        || option.getVendor() == EDbVendor.dbvgaussdb
1174                                                                        || option.getVendor() == EDbVendor.dbvpostgresql
1175                                                                        || option.getVendor() == EDbVendor.dbvmysql
1176                                                                        || option.getVendor() == EDbVendor.dbvteradata) {
1177                                                                content += ("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n");
1178                                                        } else {
1179                                                                content = SQLUtil.endTrim(content) + ";" + "\n";
1180                                                        }
1181                                                }
1182
1183                                                sqlInfo.setSql(content);
1184
1185                                                if (MetadataReader.isMetadata(content)) {
1186                                                        String hash = SHA256.getMd5(content);
1187                                                        ModelBindingManager.setGlobalHash(hash);
1188                                                        dataflow temp = new SQLDepMetadataAnalyzer().analyzeMetadata(option.getVendor(), content);
1189                                                        if (temp.getProcedures() != null) {
1190                                                                dataflow.getProcedures().addAll(temp.getProcedures());
1191                                                        }
1192                                                        if (temp.getTables() != null) {
1193                                                                dataflow.getTables().addAll(temp.getTables());
1194                                                        }
1195                                                        if (temp.getViews() != null) {
1196                                                                dataflow.getViews().addAll(temp.getViews());
1197                                                        }
1198                                                        if (temp.getResultsets() != null) {
1199                                                                dataflow.getResultsets().addAll(temp.getResultsets());
1200                                                        }
1201                                                        if (temp.getRelationships() != null) {
1202                                                                dataflow.getRelationships().addAll(temp.getRelationships());
1203                                                        }
1204                                                        if (temp.getErrors() != null) {
1205                                                                dataflow.getErrors().addAll(temp.getErrors());
1206                                                        }
1207                                                        String fileHash = SHA256.getMd5(hash);
1208                                                        if (!sqlInfoMap.containsKey(fileHash)) {
1209                                                                sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1210                                                                sqlInfoMap.get(fileHash).add(sqlInfo);
1211                                                        }
1212                                                } else {
1213                                                        String sqlHash = SHA256.getMd5(content);
1214                                                        String fileHash = SHA256.getMd5(sqlHash);
1215                                                        if (!sqlInfoMap.containsKey(fileHash)) {
1216                                                                sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1217                                                        }
1218
1219                                                        String database = TSQLEnv.DEFAULT_DB_NAME;
1220                                                        String schema = TSQLEnv.DEFAULT_SCHEMA_NAME;
1221                                                        if (sqlenv != null) {
1222                                                                database = sqlenv.getDefaultCatalogName();
1223                                                                if (database == null) {
1224                                                                        database = TSQLEnv.DEFAULT_DB_NAME;
1225                                                                }
1226                                                                schema = sqlenv.getDefaultSchemaName();
1227                                                                if (schema == null) {
1228                                                                        schema = TSQLEnv.DEFAULT_SCHEMA_NAME;
1229                                                                }
1230                                                        }
1231
1232                                                        boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor());
1233                                                        boolean supportSchema = TSQLEnv.supportSchema(option.getVendor());
1234                                                        StringBuilder builder = new StringBuilder();
1235                                                        if (supportCatalog) {
1236                                                                builder.append(database);
1237                                                        }
1238                                                        if (supportSchema) {
1239                                                                if (builder.length() > 0) {
1240                                                                        builder.append(".");
1241                                                                }
1242                                                                builder.append(schema);
1243                                                        }
1244                                                        String group = builder.toString();
1245                                                        SqlInfo sqlInfoItem = new SqlInfo();
1246                                                        sqlInfoItem.setFileName(sqlInfo.getFileName());
1247                                                        sqlInfoItem.setFilePath(sqlInfo.getFilePath());
1248                                                        sqlInfoItem.setSql(sqlInfo.getSql());
1249                                                        sqlInfoItem.setOriginIndex(0);
1250                                                        sqlInfoItem.setOriginLineStart(0);
1251                                                        sqlInfoItem.setOriginLineEnd(sqlInfo.getSql().split("\n").length - 1);
1252                                                        sqlInfoItem.setIndex(0);
1253                                                        sqlInfoItem.setLineStart(0);
1254                                                        sqlInfoItem.setLineEnd(sqlInfo.getSql().split("\n").length - 1);
1255                                                        sqlInfoItem.setHash(SHA256.getMd5(sqlHash));
1256                                                        sqlInfoItem.setGroup(group);
1257                                                        sqlInfoMap.get(fileHash).add(sqlInfoItem);
1258                                                        if (!databaseMap.containsKey(sqlHash)) {
1259                                                                databaseMap.put(sqlHash, new Pair3<StringBuilder, AtomicInteger, String>(
1260                                                                                new StringBuilder(), new AtomicInteger(), group));
1261                                                        }
1262                                                        databaseMap.get(sqlHash).first.append(sqlInfoItem.getSql());
1263                                                        databaseMap.get(sqlHash).second.incrementAndGet();
1264                                                }
1265                                        }
1266                                }
1267
1268                                boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor());
1269                                boolean supportSchema = TSQLEnv.supportSchema(option.getVendor());
1270
1271                                Iterator<String> schemaIter = databaseMap.keySet().iterator();
1272                                while (schemaIter.hasNext()) {
1273                                        if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
1274                                                break;
1275                                        }
1276                                        String key = schemaIter.next();
1277                                        String group = databaseMap.get(key).third;
1278                                        String[] split = SQLUtil.parseNames(group).toArray(new String[0]);
1279
1280                                        ModelBindingManager.removeGlobalDatabase();
1281                                        ModelBindingManager.removeGlobalSchema();
1282                                        ModelBindingManager.removeGlobalSQLEnv();
1283                                        ModelBindingManager.removeGlobalHash();
1284
1285                                        String defaultDatabase = null;
1286                                        String defaultSchema = null;
1287                                        if(sqlenv!=null){
1288                                                defaultDatabase = sqlenv.getDefaultCatalogName();
1289                                                defaultSchema = sqlenv.getDefaultSchemaName();
1290                                        }
1291                                        if (supportCatalog && supportSchema) {
1292                                                if (split.length >= 2) {
1293                                                        if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 2])) {
1294                                                                ModelBindingManager.setGlobalDatabase(split[split.length - 2]);
1295                                                                sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase());
1296                                                        }
1297                                                }
1298                                                if (split.length >= 1) {
1299                                                        if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) {
1300                                                                ModelBindingManager.setGlobalSchema(split[split.length - 1]);
1301                                                                sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema());
1302                                                        }
1303                                                }
1304                                        } else if (supportCatalog) {
1305                                                if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 1])) {
1306                                                        ModelBindingManager.setGlobalDatabase(split[split.length - 1]);
1307                                                        sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase());
1308                                                }
1309                                        } else if (supportSchema) {
1310                                                if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) {
1311                                                        ModelBindingManager.setGlobalSchema(split[split.length - 1]);
1312                                                        sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema());
1313                                                }
1314                                        }
1315                                        if (option.getHandleListener() != null) {
1316                                                option.getHandleListener().startParse(null, databaseMap.get(key).first.toString());
1317                                        }
1318
1319                                        if (sqlenv == null) {
1320                                                sqlenv = new TSQLEnv(option.getVendor()) {
1321
1322                                                        @Override
1323                                                        public void initSQLEnv() {
1324                                                                // TODO Auto-generated method stub
1325
1326                                                        }
1327                                                };
1328                                        }
1329                                        ModelBindingManager.setGlobalSQLEnv(sqlenv);
1330                                        sqlparser.sqltext = databaseMap.get(key).first.toString();
1331                                        ModelBindingManager.setGlobalHash(SHA256.getMd5(key));
1332                                        analyzeAndOutputResult(sqlparser);
1333                                        if(sqlenv!=null){
1334                                                sqlenv.setDefaultCatalogName(defaultDatabase);
1335                                                sqlenv.setDefaultSchemaName(defaultSchema);
1336                                        }
1337                                }
1338
1339                                appendProcesses(dataflow);
1340                                appendOraclePackages(dataflow);
1341                                appendProcedures(dataflow);
1342                                appendTables(dataflow);
1343                                appendViews(dataflow);
1344                                appendResultSets(dataflow);
1345                                appendRelations(dataflow);
1346                                appendErrors(dataflow);
1347                        }
1348
1349                        if (dataflow != null && option.getAnalyzeMode() != AnalyzeMode.crud) {
1350                                ModelBindingManager.setGlobalVendor(option.getVendor());
1351                                if (!isShowJoin()) {
1352                                        dataflow = mergeTables(dataflow, modelManager.TABLE_COLUMN_ID, option);
1353                                } else {
1354                                        dataflow = removeDuplicateColumns(dataflow);
1355                                }
1356                                ModelBindingManager.removeGlobalVendor();
1357                        }
1358                        
1359                        if (option.isSimpleOutput() || option.isIgnoreRecordSet()) {
1360                                List<String> showTypes = new ArrayList<>();
1361                                if(option.getSimpleShowRelationTypes()!=null) {
1362                                        showTypes.addAll(option.getSimpleShowRelationTypes());
1363                                }
1364                                if(showTypes.isEmpty()) {
1365                                        showTypes.add("fdd");
1366                                }
1367                                if(option.isShowCallRelation()) {
1368                                        showTypes.add("call");
1369                                }
1370                                if(option.isShowERDiagram()) {
1371                                        showTypes.add("er");
1372                                }
1373                                dataflow simpleDataflow = getSimpleDataflow(dataflow, option.isSimpleOutput(), showTypes);
1374                                if (simpleDataflow.getResultsets() != null) {
1375                                        for (table t : simpleDataflow.getResultsets()) {
1376                                                t.setIsTarget(null);
1377                                        }
1378                                }
1379                                return simpleDataflow;
1380                        } else {
1381                                return dataflow;
1382                        }
1383                        
1384                } catch (Exception e) {
1385                        logger.error("analyze sql failed.", e);
1386                        ErrorInfo errorInfo = new ErrorInfo();
1387                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
1388                        if (e.getMessage() == null) {
1389                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
1390                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
1391                                } else {
1392                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
1393                                }
1394                        } else {
1395                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
1396                        }
1397                        errorInfo.fillInfo(this);
1398                        errorInfos.add(errorInfo);
1399                }
1400
1401                modelManager.reset();
1402                return null;
1403        }
1404
1405        private void appendSqlInfo(Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap, int index,
1406                        SqlInfo sqlInfo, Map queryObject) {
1407                EDbVendor vendor = option.getVendor();
1408                if (!SQLUtil.isEmpty(sqlInfo.getDbVendor())) {
1409                        vendor = EDbVendor.valueOf(sqlInfo.getDbVendor());
1410                }
1411
1412                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
1413                boolean supportSchema = TSQLEnv.supportSchema(vendor);
1414
1415                String content = (String) queryObject.get("sourceCode");
1416                if (SQLUtil.isEmpty(content)) {
1417                        return;
1418                }
1419                StringBuilder builder = new StringBuilder();
1420                if (supportCatalog) {
1421                        String database = (String) queryObject.get("database");
1422                        if (database.indexOf(".") != -1) {
1423                                String delimitedChar = TSQLEnv.delimitedChar(vendor);
1424                                database = delimitedChar + SQLUtil.trimColumnStringQuote(database) + delimitedChar;
1425                        }
1426                        builder.append(database);
1427                }
1428                if (supportSchema) {
1429                        String schema = (String) queryObject.get("schema");
1430                        if (schema.indexOf(".") != -1) {
1431                                String delimitedChar = TSQLEnv.delimitedChar(vendor);
1432                                schema = delimitedChar + SQLUtil.trimColumnStringQuote(schema) + delimitedChar;
1433                        }
1434                        if (builder.length() > 0) {
1435                                builder.append(".");
1436                        }
1437                        builder.append(schema);
1438                }
1439                String group = builder.toString();
1440                String sqlHash = SHA256.getMd5(content);
1441                String hash = SHA256.getMd5(sqlHash);
1442                if (!databaseMap.containsKey(sqlHash)) {
1443                        databaseMap.put(sqlHash,
1444                                        new Pair3<StringBuilder, AtomicInteger, String>(new StringBuilder(), new AtomicInteger(), group));
1445                }
1446                TGSqlParser parser = new TGSqlParser(option.getVendor());
1447                String delimiterChar = String.valueOf(parser.getFlexer().delimiterchar);
1448                StringBuilder buffer = new StringBuilder(content);
1449                if (content.trim().endsWith(delimiterChar) || content.trim().endsWith(";")) {
1450                        buffer.append("\n");
1451                } else if(vendor == EDbVendor.dbvredshift
1452                                || vendor == EDbVendor.dbvgaussdb
1453                                || vendor == EDbVendor.dbvpostgresql
1454                                || vendor == EDbVendor.dbvmysql
1455                                || vendor == EDbVendor.dbvteradata){
1456                        buffer.append("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n");
1457                } else{
1458                        SQLUtil.endTrim(buffer);
1459                        buffer.append(";").append("\n");
1460                }
1461
1462                int lineStart = databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1;
1463                if (databaseMap.get(sqlHash).first.toString().length() == 0) {
1464                        lineStart = 0;
1465                }
1466                databaseMap.get(sqlHash).first.append(buffer.toString());
1467                SqlInfo sqlInfoItem = new SqlInfo();
1468                sqlInfoItem.setServer(sqlInfo.getServer());
1469                sqlInfoItem.setDbVendor(sqlInfo.getDbVendor());
1470                sqlInfoItem.setFileName(sqlInfo.getFileName());
1471                sqlInfoItem.setFilePath(sqlInfo.getFilePath());
1472                sqlInfoItem.setSql(buffer.toString());
1473                sqlInfoItem.setOriginIndex(index);
1474                sqlInfoItem.setOriginLineStart(0);
1475                sqlInfoItem.setOriginLineEnd(buffer.toString().split("\n", -1).length - 1);
1476                sqlInfoItem.setIndex(databaseMap.get(sqlHash).second.getAndIncrement());
1477                sqlInfoItem.setLineStart(lineStart);
1478                sqlInfoItem.setLineEnd(databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1);
1479                sqlInfoItem.setGroup(group);
1480                sqlInfoItem.setHash(hash);
1481
1482                if (!sqlInfoMap.containsKey(hash)) {
1483                        sqlInfoMap.put(hash, new ArrayList<SqlInfo>());
1484                }
1485                sqlInfoMap.get(hash).add(sqlInfoItem);
1486        }
1487
1488        static String getTextOutput(dataflow dataflow) {
1489                StringBuffer buffer = new StringBuffer();
1490                List<relationship> relations = dataflow.getRelationships();
1491                if (relations != null) {
1492                        for (int i = 0; i < relations.size(); i++) {
1493                                relationship relation = relations.get(i);
1494                                targetColumn target = relation.getTarget();
1495                                List<sourceColumn> sources = relation.getSources();
1496                                if (target != null && sources != null && sources.size() > 0) {
1497                                        buffer.append(target.getColumn()).append(" depends on: ");
1498                                        Set<String> columnSet = new LinkedHashSet<String>();
1499                                        for (int j = 0; j < sources.size(); j++) {
1500                                                sourceColumn sourceColumn = sources.get(j);
1501                                                String columnName = sourceColumn.getColumn();
1502                                                if (sourceColumn.getParent_name() != null && sourceColumn.getParent_name().length() > 0) {
1503                                                        columnName = sourceColumn.getParent_name() + "." + columnName;
1504                                                }
1505                                                columnSet.add(columnName);
1506                                        }
1507                                        String[] columns = columnSet.toArray(new String[0]);
1508                                        for (int j = 0; j < columns.length; j++) {
1509                                                buffer.append(columns[j]);
1510                                                if (j == columns.length - 1) {
1511                                                        buffer.append("\n");
1512                                                } else
1513                                                        buffer.append(", ");
1514                                        }
1515                                }
1516                        }
1517                }
1518                return buffer.toString();
1519        }
1520
1521        private String mergeRelationType(List<Pair<sourceColumn, List<String>>> typePaths) {
1522                RelationshipType relationType = RelationshipType.join;
1523                for (int i = 0; i < typePaths.size(); i++) {
1524                        List<String> path = typePaths.get(i).second;
1525                        RelationshipType type = RelationshipType.valueOf(getRelationType(path));
1526                        if (type.ordinal() < relationType.ordinal()) {
1527                                relationType = type;
1528                        }
1529                }
1530                return relationType.name();
1531        }
1532
1533        private String getRelationType(List<String> typePaths) {
1534                if (typePaths.contains("join"))
1535                        return "join";
1536                if (typePaths.contains("fdr"))
1537                        return "fdr";
1538                if (typePaths.contains("frd"))
1539                        return "frd";
1540                if (typePaths.contains("fddi"))
1541                        return "fddi";
1542                return "fdd";
1543        }
1544
1545        public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput) throws Exception {
1546                return getSimpleDataflow(instance, simpleOutput, Arrays.asList("fdd"));
1547        }
1548        
1549        public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput, List<String> types) throws Exception {
1550                ModelBindingManager.setGlobalVendor(option.getVendor());
1551                allMap.clear();
1552                targetTables.clear();
1553                resultSetMap.clear();
1554                tableMap.clear();
1555                viewMap.clear();
1556                cursorMap.clear();
1557                variableMap.clear();
1558                fileMap.clear();
1559                stageMap.clear();
1560                sequenceMap.clear();
1561                dataSourceMap.clear();
1562                databaseMap.clear();
1563                schemaMap.clear();
1564                streamMap.clear();
1565                dataflow simple = new dataflow();
1566                List<relationship> simpleRelations = new ArrayList<relationship>();
1567                List<relationship> relations = instance.getRelationships();
1568                if (instance.getResultsets() != null) {
1569                        for (table t : instance.getResultsets()) {
1570                                resultSetMap.put(t.getId().toLowerCase(), t);
1571                                allMap.put(t.getId().toLowerCase(), t);
1572                        }
1573                }
1574
1575                if (instance.getTables() != null) {
1576                        for (table t : instance.getTables()) {
1577                                tableMap.put(t.getId().toLowerCase(), t);
1578                                allMap.put(t.getId().toLowerCase(), t);
1579                        }
1580                }
1581
1582                if (instance.getViews() != null) {
1583                        for (table t : instance.getViews()) {
1584                                viewMap.put(t.getId().toLowerCase(), t);
1585                                allMap.put(t.getId().toLowerCase(), t);
1586                        }
1587                }
1588
1589                if (instance.getPaths() != null) {
1590                        for (table t : instance.getPaths()) {
1591                                fileMap.put(t.getId().toLowerCase(), t);
1592                                allMap.put(t.getId().toLowerCase(), t);
1593                        }
1594                }
1595
1596                if (instance.getStages() != null) {
1597                        for (table t : instance.getStages()) {
1598                                stageMap.put(t.getId().toLowerCase(), t);
1599                                allMap.put(t.getId().toLowerCase(), t);
1600                        }
1601                }
1602                
1603                if (instance.getSequences() != null) {
1604                        for (table t : instance.getSequences()) {
1605                                sequenceMap.put(t.getId().toLowerCase(), t);
1606                                allMap.put(t.getId().toLowerCase(), t);
1607                        }
1608                }
1609
1610                if (instance.getDatasources() != null) {
1611                        for (table t : instance.getDatasources()) {
1612                                dataSourceMap.put(t.getId().toLowerCase(), t);
1613                                allMap.put(t.getId().toLowerCase(), t);
1614                        }
1615                }
1616
1617                if (instance.getDatabases() != null) {
1618                        for (table t : instance.getDatabases()) {
1619                                databaseMap.put(t.getId().toLowerCase(), t);
1620                                allMap.put(t.getId().toLowerCase(), t);
1621                        }
1622                }
1623
1624                if (instance.getSchemas() != null) {
1625                        for (table t : instance.getSchemas()) {
1626                                schemaMap.put(t.getId().toLowerCase(), t);
1627                                allMap.put(t.getId().toLowerCase(), t);
1628                        }
1629                }
1630
1631                if (instance.getStreams() != null) {
1632                        for (table t : instance.getStreams()) {
1633                                streamMap.put(t.getId().toLowerCase(), t);
1634                                allMap.put(t.getId().toLowerCase(), t);
1635                        }
1636                }
1637
1638                if (instance.getVariables() != null) {
1639                        for (table t : instance.getVariables()) {
1640                                if(SubType.cursor.name().equals(t.getSubType())){
1641                                        cursorMap.put(t.getId().toLowerCase(), t);
1642                                }
1643                                else {
1644                                        variableMap.put(t.getId().toLowerCase(), t);
1645                                }
1646                                allMap.put(t.getId().toLowerCase(), t);
1647                        }
1648                }
1649
1650                if (relations != null) {
1651                        
1652                        List<relationship> filterRelations = new ArrayList<>();
1653                        for (relationship relationElem : relations) {
1654                                if (!types.contains(relationElem.getType()))
1655                                        continue;
1656                                else {
1657                                        filterRelations.add(relationElem);
1658                                }
1659                        }
1660                        
1661                        relations = filterRelations;
1662                        
1663                        Map<String, Set<relationship>> targetIdRelationMap = new HashMap<String, Set<relationship>>();
1664                        for (relationship relation : relations) {
1665                                if (relation.getTarget() != null) {
1666                                        String key = relation.getTarget().getParent_id() + "." + relation.getTarget().getId();
1667                                        if (!targetIdRelationMap.containsKey(key)) {
1668                                                targetIdRelationMap.put(key, new TreeSet<relationship>(new Comparator<relationship>() {
1669                                                        @Override
1670                                                        public int compare(relationship o1, relationship o2) {
1671                                                                return o1.getId().compareTo(o2.getId());
1672                                                        }
1673                                                }));
1674                                        }
1675                                        targetIdRelationMap.get(key).add(relation);
1676                                }
1677                        }
1678
1679                        Iterator<String> keys = targetIdRelationMap.keySet().iterator();
1680                        while (keys.hasNext()) {
1681                                String key = keys.next();
1682                                if (targetIdRelationMap.get(key).size() > 500) {
1683                                        keys.remove();
1684                                }
1685                        }
1686
1687                        for (relationship relationElem : relations) {
1688                                if (option.isShowCallRelation()) {
1689                                        if (RelationshipType.call.name().equals(relationElem.getType())) {
1690                                                continue;
1691                                        }
1692                                }
1693                                targetColumn target = relationElem.getTarget();
1694                                String targetParent = target.getParent_id();
1695                                if (isTarget(instance, targetParent, simpleOutput)) {
1696                                        List<Pair<sourceColumn, List<String>>> relationSources = new ArrayList<Pair<sourceColumn, List<String>>>();
1697                                        findSourceRelations(target, instance, targetIdRelationMap, relationElem, relationSources,
1698                                                        new String[] { relationElem.getType() }, simpleOutput);
1699                                        if (relationSources.size() > 0) {
1700                                                Map<sourceColumn, List<Pair<sourceColumn, List<String>>>> columnMap = new LinkedHashMap<sourceColumn, List<Pair<sourceColumn, List<String>>>>();
1701                                                for (Pair<sourceColumn, List<String>> t : relationSources) {
1702                                                        sourceColumn key = ((Pair<sourceColumn, List<String>>) t).first;
1703                                                        if (!columnMap.containsKey(key)) {
1704                                                                columnMap.put(key, new ArrayList<Pair<sourceColumn, List<String>>>());
1705                                                        }
1706                                                        columnMap.get(key).add(t);
1707                                                }
1708                                                Iterator<sourceColumn> iter = columnMap.keySet().iterator();
1709                                                Map<String, List<sourceColumn>> relationSourceMap = new HashMap<String, List<sourceColumn>>();
1710                                                while (iter.hasNext()) {
1711                                                        sourceColumn column = iter.next();
1712                                                        String relationType = mergeRelationType(columnMap.get(column));
1713                                                        if (!relationSourceMap.containsKey(relationType)) {
1714                                                                relationSourceMap.put(relationType, new ArrayList<sourceColumn>());
1715                                                        }
1716                                                        relationSourceMap.get(relationType).add(column);
1717                                                }
1718
1719                                                Iterator<String> sourceIter = relationSourceMap.keySet().iterator();
1720                                                while (sourceIter.hasNext()) {
1721                                                        String relationType = sourceIter.next();
1722                                                        relationship simpleRelation = (relationship) relationElem.clone();
1723                                                        simpleRelation.setSources(relationSourceMap.get(relationType));
1724                                                        simpleRelation.setType(relationType);
1725                                                        simpleRelation.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID));
1726                                                        simpleRelations.add(simpleRelation);
1727                                                }
1728                                        }
1729                                }
1730                        }
1731                }
1732
1733                simple.setProcedures(instance.getProcedures());
1734                simple.setPackages(instance.getPackages());
1735                simple.setProcesses(instance.getProcesses());
1736                simple.setErrors(instance.getErrors());
1737                List<table> tables = new ArrayList<table>();
1738                for (table t : instance.getTables()) {
1739                        if (!SQLUtil.isTempTable(t)) {
1740                                tables.add(t);
1741                        }
1742                        else {
1743                                if (option.isIgnoreTemporaryTable()) {
1744                                        continue;
1745                                }
1746                                else {
1747                                        tables.add(t);
1748                                }
1749                        }
1750                }
1751                simple.setStages(instance.getStages());
1752                simple.setSequences(instance.getSequences());
1753                simple.setDatasources(instance.getDatasources());
1754                simple.setStreams(instance.getStreams());
1755                simple.setPaths(instance.getPaths());
1756                simple.setTables(tables);
1757                simple.setViews(instance.getViews());
1758                if(option.isSimpleShowVariable()) {
1759                        simple.setVariables(instance.getVariables());
1760                }
1761                else if(option.isSimpleShowCursor()) {
1762                        simple.setVariables(instance.getVariables().stream().filter(t->SubType.cursor.name().equals(t.getSubType())).collect(Collectors.toList()));
1763                }
1764                if (instance.getResultsets() != null) {
1765                        List<table> resultSets = new ArrayList<table>();
1766                        for (int i = 0; i < instance.getResultsets().size(); i++) {
1767                                table resultSet = instance.getResultsets().get(i);
1768                                if (isTargetResultSet(instance, resultSet.getId(), simpleOutput)) {
1769                                        // special handle function #524 #296
1770                                        resultSets.add(resultSet);
1771                                }
1772                        }
1773                        simple.setResultsets(resultSets);
1774                }
1775
1776                List<table> functions = new ArrayList<table>();
1777                if (option.isShowCallRelation()) {
1778                        for (int i = 0; i < relations.size(); i++) {
1779                                relationship relationElem = relations.get(i);
1780                                if (!RelationshipType.call.name().equals(relationElem.getType())) {
1781                                        continue;
1782                                }
1783                                simpleRelations.add(relationElem);
1784                                for (sourceColumn callee : relationElem.getCallees()) {
1785                                        String calleeId = callee.getId();
1786                                        if (resultSetMap.containsKey(calleeId)) {
1787                                                table function = resultSetMap.get(calleeId);
1788                                                function.setIsTarget("true");
1789                                                functions.add(function);
1790                                        }
1791                                }
1792                        }
1793                }
1794
1795                if (option.isShowERDiagram()) {
1796                        for (int i = 0; i < relations.size(); i++) {
1797                                relationship relationElem = relations.get(i);
1798                                if (!RelationshipType.er.name().equals(relationElem.getType())) {
1799                                        continue;
1800                                }
1801                                simpleRelations.add(relationElem);
1802                                for (sourceColumn callee : relationElem.getCallees()) {
1803                                        String calleeId = callee.getId();
1804                                        if (resultSetMap.containsKey(calleeId)) {
1805                                                table function = resultSetMap.get(calleeId);
1806                                                function.setIsTarget("true");
1807                                                functions.add(function);
1808                                        }
1809                                }
1810                        }
1811                }
1812                
1813                if (!functions.isEmpty()) {
1814                        if (simple.getResultsets() == null) {
1815                                simple.setResultsets(functions);
1816                        } else {
1817                                simple.getResultsets().addAll(functions);
1818                        }
1819                }
1820
1821                simple.setRelationships(simpleRelations);
1822                simple.setOrientation(instance.getOrientation());
1823                targetTables.clear();
1824                resultSetMap.clear();
1825                tableMap.clear();
1826                viewMap.clear();
1827                cursorMap.clear();
1828                variableMap.clear();
1829                fileMap.clear();
1830                stageMap.clear();
1831                dataSourceMap.clear();
1832                databaseMap.clear();
1833                schemaMap.clear();
1834                streamMap.clear();
1835                return simple;
1836        }
1837
1838        private void findSourceRelations(targetColumn target, dataflow instance, Map<String, Set<relationship>> sourceIdRelationMap,
1839                        relationship targetRelation, List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, boolean simpleOutput) {
1840                findStarSourceRelations(target, instance, null, sourceIdRelationMap, targetRelation, relationSources, pathTypes,
1841                                new HashSet<String>(), new LinkedHashSet<transform>(), new LinkedHashSet<candidateTable>(), 0, simpleOutput);
1842        }
1843
1844        private void findStarSourceRelations(targetColumn target, dataflow instance, targetColumn starRelationTarget,
1845                        Map<String, Set<relationship>> sourceIdRelationMap, relationship targetRelation,
1846                        List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, Set<String> paths,
1847                        Set<transform> transforms, Set<candidateTable> candidateTables, int level, boolean simpleOutput) {
1848                if (targetRelation != null && targetRelation.getSources() != null) {
1849                        
1850                        //获取source为*的Column Parent
1851                        String starParentId = null;
1852                        for (int i = 0; i < targetRelation.getSources().size(); i++) {
1853                                sourceColumn source = targetRelation.getSources().get(i);
1854                                if (starRelationTarget != null && "*".equals(source.getColumn())) {
1855                                        starParentId = source.getParent_id();
1856                                }
1857                        }
1858                        
1859                        for (int i = 0; i < targetRelation.getSources().size(); i++) {
1860                                sourceColumn source = targetRelation.getSources().get(i);
1861                                if (starRelationTarget != null && !"*".equals(source.getColumn())
1862                                                && !DlineageUtil.getIdentifierNormalColumnName(starRelationTarget.getColumn())
1863                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(source.getColumn()))) {
1864                                        table parent = allMap.get(source.getParent_id());
1865                                        if (parent != null && isFunction(parent)) {
1866                                                // function返回值未知,不对星号做处理
1867                                        } 
1868                                        else if (parent == null) {
1869                                                continue;
1870                                        } else if(starParentId!=null && starParentId.equals(parent.getId())){
1871                                                //如果source和 * column的parent相同,则跳过
1872                                                continue;
1873                                        }
1874                                }
1875
1876                                String sourceColumnId = source.getId();
1877                                String sourceParentId = source.getParent_id();
1878                                if (sourceParentId == null || sourceColumnId == null) {
1879                                        continue;
1880                                }
1881                                if (isTarget(instance, sourceParentId, simpleOutput)) {
1882                                        List<transform> transforms2 = new ArrayList<transform>(transforms.size());
1883                                        transforms2.addAll(transforms);
1884                                        Collections.reverse(transforms2);
1885                                        
1886                                        List<candidateTable> candidateTables2 = new ArrayList<candidateTable>(candidateTables.size());
1887                                        candidateTables2.addAll(candidateTables);
1888                                        
1889                                        sourceColumn sourceColumnCopy = DlineageUtil.copySourceColumn(source);
1890                                        for (transform t : transforms2) {
1891                                                sourceColumnCopy.addTransform(t);
1892                                        }
1893                                        
1894                                        for (candidateTable t : candidateTables2) {
1895                                                sourceColumnCopy.addCandidateParent(t);
1896                                        }
1897                                        
1898                                        if(Boolean.TRUE.equals(target.isStruct()) && Boolean.TRUE.equals(source.isStruct())) {
1899                                                List<String> targetColumns = SQLUtil.parseNames(target.getColumn());
1900                                                List<String> sourceColumns = SQLUtil.parseNames(source.getColumn());
1901                                                if(!DlineageUtil.getIdentifierNormalColumnName(targetColumns.get(targetColumns.size()-1))
1902                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(sourceColumns.get(sourceColumns.size()-1)))) {
1903                                                        continue;
1904                                                }
1905                                        }
1906                                        relationSources.add(new Pair<sourceColumn, List<String>>(sourceColumnCopy, Arrays.asList(pathTypes)));
1907                                } else {
1908                                        Set<relationship> sourceRelations = sourceIdRelationMap
1909                                                        .get(source.getParent_id() + "." + source.getId());
1910                                        if (sourceRelations != null) {
1911                                                if (paths.contains(source.getParent_id() + "." + source.getId())) {
1912                                                        continue;
1913                                                } else {
1914                                                        paths.add(source.getParent_id() + "." + source.getId());
1915                                                        if (source.getTransforms() != null) {
1916                                                                transforms.addAll(source.getTransforms());
1917                                                        }
1918                                                        if (source.getCandidateParents() != null) {
1919                                                                candidateTables.addAll(source.getCandidateParents());
1920                                                        }
1921                                                }
1922                                                for (relationship relation : sourceRelations) {
1923                                                        LinkedHashSet<transform> transforms2 = new LinkedHashSet<transform>(transforms.size());
1924                                                        transforms2.addAll(transforms);
1925                                                        LinkedHashSet<candidateTable> candidateTables2 = new LinkedHashSet<candidateTable>(candidateTables.size());
1926                                                        candidateTables2.addAll(candidateTables);
1927                                                        String[] types = new String[pathTypes.length + 1];
1928                                                        types[0] = relation.getType();
1929                                                        System.arraycopy(pathTypes, 0, types, 1, pathTypes.length);
1930                                                        if (!"*".equals(source.getColumn())) {
1931                                                                findStarSourceRelations(target, instance, null, sourceIdRelationMap, relation, relationSources,
1932                                                                                types, paths, transforms2, candidateTables2, level + 1, simpleOutput);
1933                                                        } else {
1934                                                                findStarSourceRelations(target, instance,
1935                                                                                starRelationTarget == null ? targetRelation.getTarget() : starRelationTarget,
1936                                                                                sourceIdRelationMap, relation, relationSources, types, paths, transforms, candidateTables2,
1937                                                                                level + 1, simpleOutput);
1938                                                        }
1939                                                }
1940                                        }
1941                                }
1942                        }
1943                }
1944        }
1945
1946        private Map<String, Boolean> targetTables = new HashMap<String, Boolean>();
1947        private Map<String, table> resultSetMap = new HashMap<String, table>();
1948        private Map<String, table> tableMap = new HashMap<String, table>();
1949        private Map<String, table> viewMap = new HashMap<String, table>();
1950        private Map<String, table> cursorMap = new HashMap<String, table>();
1951        private Map<String, table> variableMap = new HashMap<String, table>();
1952        private Map<String, table> fileMap = new HashMap<String, table>();
1953        private Map<String, table> stageMap = new HashMap<String, table>();
1954        private Map<String, table> sequenceMap = new HashMap<String, table>();
1955        private Map<String, table> dataSourceMap = new HashMap<String, table>();
1956        private Map<String, table> databaseMap = new HashMap<String, table>();
1957        private Map<String, table> schemaMap = new HashMap<String, table>();
1958        private Map<String, table> streamMap = new HashMap<String, table>();
1959        private Map<String, table> allMap = new HashMap<String, table>();
1960
1961        private boolean isTarget(dataflow instance, String targetParentId, boolean simpleOutput) {
1962                if (targetTables.containsKey(targetParentId))
1963                        return targetTables.get(targetParentId);
1964                if (isTable(instance, targetParentId)) {
1965                        targetTables.put(targetParentId, true);
1966                        return true;
1967                } else if (isView(instance, targetParentId)) {
1968                        targetTables.put(targetParentId, true);
1969                        return true;
1970                } else if (isFile(instance, targetParentId)) {
1971                        targetTables.put(targetParentId, true);
1972                        return true;
1973                } else if (isDatabase(instance, targetParentId)) {
1974                        targetTables.put(targetParentId, true);
1975                        return true;
1976                } else if (isSchema(instance, targetParentId)) {
1977                        targetTables.put(targetParentId, true);
1978                        return true;
1979                } else if (isStage(instance, targetParentId)) {
1980                        targetTables.put(targetParentId, true);
1981                        return true;
1982                } else if (isSequence(instance, targetParentId)) {
1983                        targetTables.put(targetParentId, true);
1984                        return true;
1985                } else if (isDataSource(instance, targetParentId)) {
1986                        targetTables.put(targetParentId, true);
1987                        return true;
1988                } else if (isStream(instance, targetParentId)) {
1989                        targetTables.put(targetParentId, true);
1990                        return true;
1991                } else if (isCursor(instance, targetParentId) && option.isSimpleShowCursor()) {
1992                        targetTables.put(targetParentId, true);
1993                        return true;
1994                } else if ((isVariable(instance, targetParentId) || isCursor(instance, targetParentId)) && option.isSimpleShowVariable()) {
1995                        targetTables.put(targetParentId, true);
1996                        return true;
1997                } else if (isTargetResultSet(instance, targetParentId, simpleOutput)) {
1998                        targetTables.put(targetParentId, true);
1999                        return true;
2000                }
2001                targetTables.put(targetParentId, false);
2002                return false;
2003        }
2004
2005        private boolean isTargetResultSet(dataflow instance, String targetParent, boolean simpleOutput) {
2006                if (resultSetMap.containsKey(targetParent.toLowerCase())) {
2007                        table result = resultSetMap.get(targetParent.toLowerCase());
2008                        boolean isTarget = result.isTarget();
2009                        Option option = ModelBindingManager.getGlobalOption();
2010                        if (option != null && option.isSqlflowIgnoreFunction() && isFunction(result)) {
2011                                return false;
2012                        }
2013                        if (isTarget && simpleOutput) {
2014                                if (option != null && option.isSimpleShowFunction() && isFunction(result)) {
2015                                        return true;
2016
2017                                } else if (option != null && option.isSimpleShowTopSelectResultSet()) {
2018                                        return true;
2019                                }
2020                                if (ResultSetType.of(result.getType()) != null && option.containsResultSetType(ResultSetType.of(result.getType()))) {
2021                                        return true;
2022                                }
2023                        } else
2024                                return isTarget;
2025                }
2026                return false;
2027        }
2028
2029        private boolean isFunction(table resultSet) {
2030                if("function".equals(resultSet.getType())){
2031                        return true;
2032                }
2033                else if("resultset".equals(resultSet.getType()) && "function".equals(resultSet.getSubType())){
2034                        return true;
2035                }
2036                return false;
2037        }
2038
2039        private boolean isView(dataflow instance, String targetParent) {
2040                if (viewMap.containsKey(targetParent.toLowerCase())) {
2041                        return true;
2042                }
2043                return false;
2044        }
2045
2046        private boolean isCursor(dataflow instance, String targetParent) {
2047                if (cursorMap.containsKey(targetParent.toLowerCase())) {
2048                        return true;
2049                }
2050                return false;
2051        }
2052
2053        private boolean isVariable(dataflow instance, String targetParent) {
2054                if (variableMap.containsKey(targetParent.toLowerCase())) {
2055                        return true;
2056                }
2057                return false;
2058        }
2059
2060        private boolean isFile(dataflow instance, String targetParent) {
2061                if (fileMap.containsKey(targetParent.toLowerCase())) {
2062                        return true;
2063                }
2064                return false;
2065        }
2066
2067        private boolean isStage(dataflow instance, String targetParent) {
2068                if (stageMap.containsKey(targetParent.toLowerCase())) {
2069                        return true;
2070                }
2071                return false;
2072        }
2073        
2074        private boolean isSequence(dataflow instance, String targetParent) {
2075                if (sequenceMap.containsKey(targetParent.toLowerCase())) {
2076                        return true;
2077                }
2078                return false;
2079        }
2080
2081        private boolean isDataSource(dataflow instance, String targetParent) {
2082                if (dataSourceMap.containsKey(targetParent.toLowerCase())) {
2083                        return true;
2084                }
2085                return false;
2086        }
2087
2088        private boolean isDatabase(dataflow instance, String targetParent) {
2089                if (databaseMap.containsKey(targetParent.toLowerCase())) {
2090                        return true;
2091                }
2092                return false;
2093        }
2094
2095        private boolean isSchema(dataflow instance, String targetParent) {
2096                if (schemaMap.containsKey(targetParent.toLowerCase())) {
2097                        return true;
2098                }
2099                return false;
2100        }
2101
2102        private boolean isStream(dataflow instance, String targetParent) {
2103                if (streamMap.containsKey(targetParent.toLowerCase())) {
2104                        return true;
2105                }
2106                return false;
2107        }
2108
2109        private boolean isTable(dataflow instance, String targetParent) {
2110                if (tableMap.containsKey(targetParent.toLowerCase())) {
2111                        if (SQLUtil.isTempTable(tableMap.get(targetParent))) {
2112                                if (option.isIgnoreTemporaryTable()) {
2113                                        return false;
2114                                }
2115                        }
2116                        if (tableMap.get(targetParent).isFunction()) {
2117                                if (option != null && option.isSimpleShowFunction()) {
2118                                        return true;
2119                                } else {
2120                                        return false;
2121                                }
2122                        }
2123                        if (SubType.synonym.name().equals(tableMap.get(targetParent).getSubType())) {
2124                                if (option != null && option.isSimpleShowSynonym()) {
2125                                        return true;
2126                                } else {
2127                                        return false;
2128                                }
2129                        }
2130                        return true;
2131                } else {
2132                        return false;
2133                }
2134        }
2135
2136        private void init() {
2137                metadataErrors.clear();
2138                sqlInfoMap.clear();
2139                errorInfos.clear();
2140                dataflow = null;
2141                dataflowString = null;
2142                ModelBindingManager.removeGlobalDatabase();
2143                ModelBindingManager.removeGlobalSchema();
2144                ModelBindingManager.removeGlobalVendor();
2145                ModelBindingManager.removeGlobalSQLEnv();
2146                ModelBindingManager.removeGlobalHash();
2147                appendResultSets.clear();
2148                appendStarColumns.clear();
2149                appendTableStarColumns.clear();
2150                modelManager.TABLE_COLUMN_ID = option.getStartId();
2151                modelManager.RELATION_ID = option.getStartId();
2152                modelManager.DISPLAY_ID.clear();
2153                modelManager.DISPLAY_NAME.clear();
2154                tableIds.clear();
2155                ModelBindingManager.setGlobalVendor(option.getVendor());
2156                modelManager.reset();
2157        }
2158
2159        private String getErrorMessage(TSyntaxError error, String errorType) {
2160                String s = "", hint = "Syntax error";
2161                if (ErrorInfo.SYNTAX_HINT.equals(errorType)) {
2162                        hint = "Syntax hint";
2163                }
2164                if (error.hint.length() > 0)
2165                        hint = error.hint;
2166                s = s + hint + "(" + error.errorno + ") near: " + error.tokentext;
2167                s = s + "(" + error.lineNo;
2168                s = s + "," + error.columnNo + ")";
2169                return s;
2170        }
2171
2172        boolean OLD_ENABLE_RESOLVER = TBaseType.ENABLE_RESOLVER;
2173        private void analyzeAndOutputResult(TGSqlParser sqlparser) {
2174                try {
2175                        accessedSubqueries.clear();
2176                        accessedStatements.clear();
2177                        stmtStack.clear();
2178                        viewDDLMap.clear();
2179                        procedureDDLMap.clear();
2180                        OLD_ENABLE_RESOLVER = TBaseType.ENABLE_RESOLVER;
2181                        TBaseType.ENABLE_RESOLVER = true;
2182                        try {
2183                                int result = sqlparser.parse();
2184                                if (result != 0) {
2185                                        ArrayList<TSyntaxError> errors = sqlparser.getSyntaxErrors();
2186                                        if (errors != null && !errors.isEmpty()) {
2187                                                for (int i = 0; i < errors.size(); i++) {
2188                                                        TSyntaxError error = errors.get(i);
2189                                                        ErrorInfo errorInfo = new ErrorInfo();
2190                                                        errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
2191                                                        errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
2192                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2193                                                                        ModelBindingManager.getGlobalHash()));
2194                                                        String[] segments = error.tokentext.split("\n");
2195                                                        if (segments.length == 1) {
2196                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2197                                                                                error.columnNo + error.tokentext.length(),
2198                                                                                ModelBindingManager.getGlobalHash()));
2199                                                        } else {
2200                                                                errorInfo.setEndPosition(
2201                                                                                new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2202                                                                                                (long) segments[segments.length - 1].length() + 1,
2203                                                                                                ModelBindingManager.getGlobalHash()));
2204                                                        }
2205                                                        ;
2206                                                        errorInfo.fillInfo(this);
2207                                                        errorInfos.add(errorInfo);
2208                                                }
2209                                        }
2210                                }
2211
2212                                if (option.getHandleListener() != null) {
2213                                        option.getHandleListener().endParse(result == 0);
2214                                }
2215                        } catch (Exception e) {
2216                                if (option.getHandleListener() != null) {
2217                                        option.getHandleListener().endParse(false);
2218                                }
2219                                ErrorInfo errorInfo = new ErrorInfo();
2220                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
2221                                if (e.getMessage() == null) {
2222                                        if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
2223                                                errorInfo
2224                                                                .setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
2225                                        } else {
2226                                                errorInfo.setErrorMessage(e.getClass().getSimpleName());
2227                                        }
2228                                } else {
2229                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
2230                                }
2231                                errorInfo.fillInfo(this);
2232                                errorInfos.add(errorInfo);
2233                                return;
2234                        }
2235
2236                        if (option.getHandleListener() != null) {
2237                                option.getHandleListener().startAnalyzeDataFlow(sqlparser);
2238                        }
2239
2240                        for (int i = 0; i < sqlparser.getSqlstatements().size(); i++) {
2241                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2242                                        break;
2243                                }
2244
2245                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2246                                if (stmt.getErrorCount() == 0) {
2247                                        if (stmt.getParentStmt() == null) {
2248                                                modelManager.collectSqlHash(stmt);
2249                                                if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema
2250                                                                || stmt instanceof TCreateTableSqlStatement
2251                                                                || stmt instanceof TCreateExternalDataSourceStmt || stmt instanceof TCreateStageStmt
2252                                                                || stmt instanceof TMssqlCreateType
2253                                                                || stmt instanceof TMssqlDeclare
2254                                                                || (stmt instanceof TCreateFunctionStmt && hasDb2ReturnStmt((TCreateFunctionStmt)stmt))
2255                                                                || (stmt instanceof TMssqlCreateFunction
2256                                                                                && (((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null
2257                                                                                                || ((TMssqlCreateFunction) stmt).getReturnStmt() != null))) {
2258                                                        boolean listen = false;
2259                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2260                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2261                                                                listen = true;
2262                                                        }
2263                                                        analyzeCustomSqlStmt(stmt);
2264                                                        if (listen && option.getHandleListener() != null) {
2265                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2266                                                        }
2267                                                }
2268                                        }
2269                                }
2270                        }
2271
2272                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2273                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2274                                        break;
2275                                }
2276
2277                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2278                                if (stmt.getErrorCount() == 0) {
2279                                        if (stmt.getParentStmt() == null) {
2280                                                if (stmt instanceof TUseDatabase 
2281                                                                || stmt instanceof TUseSchema
2282                                                                || stmt instanceof TCreateViewSqlStatement 
2283                                                                || stmt instanceof TCreateSynonymStmt 
2284                                                                || stmt instanceof TStoredProcedureSqlStatement) {
2285                                                        boolean listen = false;
2286                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2287                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2288                                                                listen = true;
2289                                                        }
2290                                                        if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema) {
2291                                                                analyzeCustomSqlStmt(stmt);
2292                                                        } else if (stmt instanceof TCreateViewSqlStatement) {
2293                                                                TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt;
2294                                                                viewDDLMap.put(DlineageUtil.getTableFullName(view.getViewName().toString()), view);
2295                                                        } else if (stmt instanceof TCreateSynonymStmt) {
2296                                                                TCreateSynonymStmt synonym = (TCreateSynonymStmt) stmt;
2297                                                                if(synonym.getSynonymName()!=null) {
2298                                                                        viewDDLMap.put(DlineageUtil.getTableFullName(synonym.getSynonymName().toString()), synonym);
2299                                                                }
2300                                                        } else if (stmt instanceof TStoredProcedureSqlStatement) {
2301                                                                TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) stmt;
2302                                                                if(procedure.getStoredProcedureName() == null) {
2303                                                                        continue;
2304                                                                }
2305                                                                procedureDDLMap.put(DlineageUtil.getProcedureNameWithArgNum(procedure), procedure);
2306                                                        }
2307                                                        if (listen && option.getHandleListener() != null) {
2308                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2309                                                        }
2310                                                }
2311                                        }
2312                                }
2313                        }
2314
2315                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2316                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2317                                        break;
2318                                }
2319
2320                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2321                                if (stmt.getErrorCount() == 0) {
2322                                        if (stmt.getParentStmt() == null) {
2323                                                if (stmt instanceof TUseDatabase 
2324                                                                || stmt instanceof TUseSchema
2325                                                                || stmt instanceof TCreateViewSqlStatement 
2326                                                                || stmt instanceof TCreateSynonymStmt) {
2327                                                        boolean listen = false;
2328                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2329                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2330                                                                listen = true;
2331                                                        }
2332                                                        analyzeCustomSqlStmt(stmt);
2333                                                        if (listen && option.getHandleListener() != null) {
2334                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2335                                                        }
2336                                                }
2337                                        }
2338                                }
2339                        }
2340
2341                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2342                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2343                                        break;
2344                                }
2345
2346                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2347                                if (stmt.getErrorCount() == 0) {
2348                                        if (stmt.getParentStmt() == null) {
2349                                                if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema
2350                                                                || stmt instanceof TStoredProcedureSqlStatement) {
2351                                                        boolean listen = false;
2352                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2353                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2354                                                                listen = true;
2355                                                        }
2356                                                        if (stmt instanceof TPlsqlCreateTrigger)
2357                                                                continue;
2358                                                        analyzeCustomSqlStmt(stmt);
2359                                                        if (listen && option.getHandleListener() != null) {
2360                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2361                                                        }
2362                                                }
2363                                        }
2364                                }
2365                        }
2366
2367                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2368                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2369                                        break;
2370                                }
2371
2372                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2373
2374                                if (option.isIgnoreTopSelect()) {
2375                                        if ((stmt instanceof TSelectSqlStatement && ((TSelectSqlStatement)stmt).getIntoClause() == null) || stmt instanceof TRedshiftDeclare
2376                                                        || stmt instanceof TRedshiftDeclare) {
2377                                                continue;
2378                                        }
2379                                }
2380
2381                                if (stmt.getErrorCount() == 0) {
2382                                        if (stmt.getParentStmt() == null) {
2383                                                if (!(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TCreateStageStmt)
2384                                                                && !(stmt instanceof TCreateExternalDataSourceStmt)
2385                                                                && !(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TMssqlDeclare)
2386                                                                && !(stmt instanceof TMssqlCreateFunction
2387                                                                                && ((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null)) {
2388                                                        boolean listen = false;
2389                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2390                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2391                                                                listen = true;
2392                                                        }
2393                                                        analyzeCustomSqlStmt(stmt);
2394                                                        if (listen && option.getHandleListener() != null) {
2395                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2396                                                        }
2397                                                }
2398                                        }
2399                                }
2400                        }
2401
2402                        if (option.getHandleListener() != null) {
2403                                option.getHandleListener().endAnalyzeDataFlow(sqlparser);
2404                        }
2405                } catch (Throwable e) {
2406                        logger.error("analyze sql failed.", e);
2407                        ErrorInfo errorInfo = new ErrorInfo();
2408                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
2409                        if (e.getMessage() == null) {
2410                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
2411                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
2412                                } else {
2413                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
2414                                }
2415                        } else {
2416                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
2417                        }
2418                        errorInfo.fillInfo(this);
2419                        errorInfos.add(errorInfo);
2420                }
2421                finally {
2422                        TBaseType.ENABLE_RESOLVER = OLD_ENABLE_RESOLVER;
2423                }
2424
2425        }
2426
2427        private boolean hasDb2ReturnStmt(TCreateFunctionStmt stmt) {
2428                if (stmt.getReturnStmt() != null) {
2429                        return true;
2430                }
2431                if (stmt.getBodyStatements() != null) {
2432                        for (int i = 0; i < stmt.getBodyStatements().size(); i++) {
2433                                if(stmt.getBodyStatements().get(i) instanceof TDb2ReturnStmt) {
2434                                        return true;
2435                                }
2436                        }
2437                }
2438                return false;
2439        }
2440
2441        private void analyzeCustomSqlStmt(TCustomSqlStatement stmt) {
2442                if (!accessedStatements.contains(stmt)) {
2443                        accessedStatements.add(stmt);
2444                } else if (!(stmt instanceof TUseDatabase || stmt instanceof TUseSchema)) {
2445                        return;
2446                }
2447
2448                ArrayList<TSyntaxError> errors = stmt.getSyntaxHints();
2449                if (errors != null && !errors.isEmpty()) {
2450                        for (int i = 0; i < errors.size(); i++) {
2451                                TSyntaxError error = errors.get(i);
2452                                ErrorInfo errorInfo = new ErrorInfo();
2453                                errorInfo.setErrorType(ErrorInfo.SYNTAX_HINT);
2454                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_HINT));
2455                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2456                                                ModelBindingManager.getGlobalHash()));
2457                                String[] segments = error.tokentext.split("\n");
2458                                if (segments.length == 1) {
2459                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2460                                                        error.columnNo + error.tokentext.length(), ModelBindingManager.getGlobalHash()));
2461                                } else {
2462                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2463                                                        (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash()));
2464                                }
2465                                errorInfo.fillInfo(this);
2466                                errorInfos.add(errorInfo);
2467                        }
2468                }
2469
2470                if (option.getAnalyzeMode() == AnalyzeMode.dynamic) {
2471                        if (!(stmt instanceof TStoredProcedureSqlStatement
2472                                        || stmt instanceof TExecuteSqlStatement
2473                                        || stmt instanceof TMssqlExecute
2474                                        || stmt instanceof TExecImmeStmt)) {
2475                                return;
2476                        }
2477                }
2478
2479                if(DlineageUtil.getTopStmt(stmt) == stmt){
2480                        modelManager.collectSqlHash(stmt);
2481                }
2482
2483                try {
2484                        if (stmt instanceof TUseDatabase) {
2485                                if (((TUseDatabase) stmt).getDatabaseName() != null) {
2486                                        ModelBindingManager.setGlobalDatabase(((TUseDatabase) stmt).getDatabaseName().toString());
2487                                }
2488                        } else if (stmt instanceof TUseSchema) {
2489                                if (((TUseSchema) stmt).getSchemaName() != null) {
2490                                        String schemaName = ((TUseSchema) stmt).getSchemaName().toString();
2491                                        List<String> splits = SQLUtil.parseNames(schemaName);
2492                                        if (splits.size() == 1) {
2493                                                ModelBindingManager.setGlobalSchema(schemaName);
2494                                        } else if (splits.size() > 1) {
2495                                                ModelBindingManager.setGlobalSchema(splits.get(splits.size() - 1));
2496                                                ModelBindingManager.setGlobalDatabase(splits.get(splits.size() - 2));
2497                                        }
2498                                }
2499                        } else if (stmt instanceof TPlsqlRecordTypeDefStmt) {
2500                                this.stmtStack.push(stmt);
2501                                this.analyzePlsqlRecordTypeDefStmt((TPlsqlRecordTypeDefStmt) stmt);
2502                                this.stmtStack.pop();
2503                        } else if (stmt instanceof TPlsqlTableTypeDefStmt) {
2504                                this.stmtStack.push(stmt);
2505                                this.analyzePlsqlTableTypeDefStmt((TPlsqlTableTypeDefStmt) stmt);
2506                                this.stmtStack.pop();
2507                        } else if (stmt instanceof TStoredProcedureSqlStatement) {
2508                                this.stmtStack.push(stmt);
2509                                this.analyzeStoredProcedureStmt((TStoredProcedureSqlStatement) stmt);
2510                                this.stmtStack.pop();
2511                        } else if (stmt instanceof TCreateTableSqlStatement) {
2512                                stmtStack.push(stmt);
2513                                analyzeCreateTableStmt((TCreateTableSqlStatement) stmt);
2514                                stmtStack.pop();
2515                        } else if (stmt instanceof TCreateStageStmt) {
2516                                stmtStack.push(stmt);
2517                                analyzeCreateStageStmt((TCreateStageStmt) stmt);
2518                                stmtStack.pop();
2519                        } else if (stmt instanceof TCreateExternalDataSourceStmt) {
2520                                stmtStack.push(stmt);
2521                                analyzeCreateExternalDataSourceStmt((TCreateExternalDataSourceStmt) stmt);
2522                                stmtStack.pop();
2523                        } else if (stmt instanceof TCreateStreamStmt) {
2524                                stmtStack.push(stmt);
2525                                analyzeCreateStreamStmt((TCreateStreamStmt) stmt);
2526                                stmtStack.pop();
2527                        } else if (stmt instanceof TSelectSqlStatement) {
2528                                analyzeSelectStmt((TSelectSqlStatement) stmt);
2529                        } else if (stmt instanceof TDropTableSqlStatement) {
2530                                stmtStack.push(stmt);
2531                                analyzeDropTableStmt((TDropTableSqlStatement) stmt);
2532                                stmtStack.pop();
2533                        } else if (stmt instanceof TTruncateStatement) {
2534                                stmtStack.push(stmt);
2535                                analyzeTruncateTableStmt((TTruncateStatement) stmt);
2536                                stmtStack.pop();
2537                        } else if (stmt instanceof TCreateMaterializedSqlStatement) {
2538                                stmtStack.push(stmt);
2539                                TCreateMaterializedSqlStatement view = (TCreateMaterializedSqlStatement) stmt;
2540                                analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName());
2541                                stmtStack.pop();
2542                        } else if (stmt instanceof TCreateViewSqlStatement) {
2543                                stmtStack.push(stmt);
2544                                TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt;
2545                                analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName());
2546                                stmtStack.pop();
2547                        } else if(stmt instanceof TDb2SqlVariableDeclaration){
2548                                stmtStack.push(stmt);
2549                                analyzeDb2Declare((TDb2SqlVariableDeclaration)stmt);
2550                                stmtStack.pop();
2551                        } else if (stmt instanceof TMssqlCreateType) {
2552                                stmtStack.push(stmt);
2553                                TMssqlCreateType createType = (TMssqlCreateType) stmt;
2554                                analyzeMssqlCreateType(createType);
2555                                stmtStack.pop();
2556                        } else if (stmt instanceof TMssqlDeclare) {
2557                                stmtStack.push(stmt);
2558                                TMssqlDeclare declare = (TMssqlDeclare) stmt;
2559                                analyzeMssqlDeclare(declare);
2560                                stmtStack.pop();
2561                        } else if (stmt instanceof TInsertSqlStatement) {
2562                                stmtStack.push(stmt);
2563                                TInsertSqlStatement insert = (TInsertSqlStatement)stmt;
2564                                analyzeInsertStmt(insert);
2565                                if(insert.getMultiInsertStatements()!=null) {
2566                                        for(int i=0;i<insert.getMultiInsertStatements().size();i++) {
2567                                                analyzeInsertStmt(insert.getMultiInsertStatements().get(i));
2568                                        }
2569                                }
2570                                stmtStack.pop();
2571                        } else if (stmt instanceof TRedshiftCopy) {
2572                                stmtStack.push(stmt);
2573                                analyzeRedshiftCopyStmt((TRedshiftCopy) stmt);
2574                                stmtStack.pop();
2575                        } else if (stmt instanceof TSnowflakeCopyIntoStmt) {
2576                                stmtStack.push(stmt);
2577                                analyzeCopyIntoStmt((TSnowflakeCopyIntoStmt) stmt);
2578                                stmtStack.pop();
2579                        } else if (stmt instanceof TUnloadStmt) {
2580                                stmtStack.push(stmt);
2581                                analyzeUnloadStmt((TUnloadStmt) stmt);
2582                                stmtStack.pop();
2583                        } else if (stmt instanceof TUpdateSqlStatement) {
2584                                stmtStack.push(stmt);
2585                                analyzeUpdateStmt((TUpdateSqlStatement) stmt);
2586                                stmtStack.pop();
2587                        } else if (stmt instanceof TMergeSqlStatement) {
2588                                stmtStack.push(stmt);
2589                                analyzeMergeStmt((TMergeSqlStatement) stmt);
2590                                stmtStack.pop();
2591                        } else if (stmt instanceof TDeleteSqlStatement) {
2592                                stmtStack.push(stmt);
2593                                analyzeDeleteStmt((TDeleteSqlStatement) stmt);
2594                                stmtStack.pop();
2595                        } else if (stmt instanceof TCursorDeclStmt) {
2596                                stmtStack.push(stmt);
2597                                analyzeCursorDeclStmt((TCursorDeclStmt) stmt);
2598                                stmtStack.pop();
2599                        } else if (stmt instanceof TFetchStmt) {
2600                                stmtStack.push(stmt);
2601                                analyzeFetchStmt((TFetchStmt) stmt);
2602                                stmtStack.pop();
2603                        } else if (stmt instanceof TMssqlFetch) {
2604                                stmtStack.push(stmt);
2605                                analyzeFetchStmt((TMssqlFetch) stmt);
2606                                stmtStack.pop();
2607                        } else if (stmt instanceof TForStmt) {
2608                                stmtStack.push(stmt);
2609                                analyzeForStmt((TForStmt) stmt);
2610                                stmtStack.pop();
2611                        } else if (stmt instanceof TOpenforStmt) {
2612                                stmtStack.push(stmt);
2613                                analyzeOpenForStmt((TOpenforStmt) stmt);
2614                                stmtStack.pop();
2615                        } else if (stmt instanceof TLoopStmt) {
2616                                stmtStack.push(stmt);
2617                                analyzeLoopStmt((TLoopStmt) stmt);
2618                                stmtStack.pop();
2619                        } else if (stmt instanceof TAssignStmt) {
2620                                stmtStack.push(stmt);
2621                                analyzeAssignStmt((TAssignStmt) stmt);
2622                                stmtStack.pop();
2623                        } else if (stmt instanceof TSetStmt) {
2624                                stmtStack.push(stmt);
2625                                analyzeSetStmt((TSetStmt) stmt);
2626                                stmtStack.pop();
2627                        } else if (stmt instanceof TMssqlSet) {
2628                                stmtStack.push(stmt);
2629                                analyzeMssqlSetStmt((TMssqlSet) stmt);
2630                                stmtStack.pop();
2631                        } else if (stmt instanceof TVarDeclStmt) {
2632                                stmtStack.push(stmt);
2633                                analyzeVarDeclStmt((TVarDeclStmt) stmt);
2634                                stmtStack.pop();
2635                        } else if (stmt instanceof TCreateDatabaseSqlStatement) {
2636                                stmtStack.push(stmt);
2637                                analyzeCloneDatabaseStmt((TCreateDatabaseSqlStatement) stmt);
2638                                stmtStack.pop();
2639                        } else if (stmt instanceof TCreateSchemaSqlStatement) {
2640                                stmtStack.push(stmt);
2641                                analyzeCloneSchemaStmt((TCreateSchemaSqlStatement) stmt);
2642                                stmtStack.pop();
2643                        } else if (stmt instanceof TAlterTableStatement) {
2644                                stmtStack.push(stmt);
2645                                analyzeAlterTableStmt((TAlterTableStatement) stmt);
2646                                stmtStack.pop();
2647                        } else if (stmt instanceof TRenameStmt) {
2648                                stmtStack.push(stmt);
2649                                analyzeRenameStmt((TRenameStmt) stmt);
2650                                stmtStack.pop();
2651                        } else if (stmt instanceof TCreateSynonymStmt) {
2652                                stmtStack.push(stmt);
2653                                analyzeCreateSynonymStmt((TCreateSynonymStmt) stmt);
2654                                stmtStack.pop();
2655                        } else if (stmt instanceof TLoadDataStmt) {
2656                                stmtStack.push(stmt);
2657                                analyzeLoadDataStmt((TLoadDataStmt) stmt);
2658                                stmtStack.pop();
2659                        } else if (stmt instanceof THiveLoad) {
2660                                stmtStack.push(stmt);
2661                                analyzeHiveLoadStmt((THiveLoad) stmt);
2662                                stmtStack.pop();
2663                        } else if (stmt instanceof TDb2ReturnStmt) {
2664                                stmtStack.push(stmt);
2665                                analyzeDb2ReturnStmt((TDb2ReturnStmt) stmt);
2666                                stmtStack.pop();
2667                        } else if (stmt instanceof TReturnStmt) {
2668                                stmtStack.push(stmt);
2669                                analyzeReturnStmt((TReturnStmt) stmt);
2670                                stmtStack.pop();
2671                        } else if (stmt instanceof TMssqlReturn) {
2672                                stmtStack.push(stmt);
2673                                analyzeMssqlReturnStmt((TMssqlReturn) stmt);
2674                                stmtStack.pop();
2675                        } else if (stmt instanceof TExecuteSqlStatement) {
2676                                String sqlText = ((TExecuteSqlStatement) stmt).getPreparedSqlText();
2677                                if(sqlText == null) {
2678                                        sqlText = ((TExecuteSqlStatement) stmt).getSqlText();
2679                                }
2680                                if (sqlText != null) {
2681                                        modelManager.collectDynamicSqlHash(stmt);
2682                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
2683                                        sqlparser.sqltext = SQLUtil.trimColumnStringQuote(sqlText);
2684                                        int result = sqlparser.parse();
2685                                        if (result != 0) {
2686                                                errors = sqlparser.getSyntaxErrors();
2687                                                if (errors != null && !errors.isEmpty()) {
2688                                                        for (int i = 0; i < errors.size(); i++) {
2689                                                                TSyntaxError error = errors.get(i);
2690                                                                ErrorInfo errorInfo = new ErrorInfo();
2691                                                                errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
2692                                                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
2693                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2694                                                                                ModelBindingManager.getGlobalHash()));
2695                                                                String[] segments = error.tokentext.split("\n");
2696                                                                if (segments.length == 1) {
2697                                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2698                                                                                        error.columnNo + error.tokentext.length(),
2699                                                                                        ModelBindingManager.getGlobalHash()));
2700                                                                } else {
2701                                                                        errorInfo.setEndPosition(
2702                                                                                        new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2703                                                                                                        (long) segments[segments.length - 1].length() + 1,
2704                                                                                                        ModelBindingManager.getGlobalHash()));
2705                                                                }
2706                                                                errorInfo.fillInfo(this);
2707                                                                errorInfos.add(errorInfo);
2708                                                        }
2709                                                }
2710                                        } else if (sqlparser.sqlstatements != null) {
2711                                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2712                                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
2713                                                }
2714                                        }
2715                                }
2716                                else if (((TExecuteSqlStatement) stmt).getStmtString() != null) {
2717                                        modelManager.collectDynamicSqlHash(stmt);
2718                                }
2719                        } else if (stmt instanceof TMssqlExecute) {
2720                                TMssqlExecute executeStmt = (TMssqlExecute)stmt;
2721                                if (executeStmt.getSqlText() != null) {
2722                                        modelManager.collectDynamicSqlHash(stmt);
2723                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
2724                                        sqlparser.sqltext = ((TMssqlExecute) stmt).getSqlText();
2725                                        int result = sqlparser.parse();
2726                                        if (result != 0) {
2727                                                errors = sqlparser.getSyntaxErrors();
2728                                                if (errors != null && !errors.isEmpty()) {
2729                                                        for (int i = 0; i < errors.size(); i++) {
2730                                                                TSyntaxError error = errors.get(i);
2731                                                                ErrorInfo errorInfo = new ErrorInfo();
2732                                                                errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
2733                                                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
2734                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2735                                                                                ModelBindingManager.getGlobalHash()));
2736                                                                String[] segments = error.tokentext.split("\n");
2737                                                                if (segments.length == 1) {
2738                                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2739                                                                                        error.columnNo + error.tokentext.length(),
2740                                                                                        ModelBindingManager.getGlobalHash()));
2741                                                                } else {
2742                                                                        errorInfo.setEndPosition(
2743                                                                                        new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2744                                                                                                        (long) segments[segments.length - 1].length() + 1,
2745                                                                                                        ModelBindingManager.getGlobalHash()));
2746                                                                }
2747                                                                errorInfo.fillInfo(this);
2748                                                                errorInfos.add(errorInfo);
2749                                                        }
2750                                                }
2751                                        } else if (sqlparser.sqlstatements != null) {
2752                                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2753                                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
2754                                                }
2755                                        }
2756                                } else if (executeStmt.getModuleName() != null) {
2757                                        stmtStack.push(stmt);
2758                                        analyzeMssqlExecute(executeStmt);
2759                                        stmtStack.pop();
2760                                }
2761                        } else if (stmt instanceof TExecImmeStmt) {
2762                                TExecImmeStmt execImmeStmt = (TExecImmeStmt) stmt;
2763                                modelManager.collectDynamicSqlHash(stmt);
2764                                synchronized (DataFlowAnalyzer.class) {
2765                                        TStatementList stmts = execImmeStmt.getDynamicStatements();
2766                                        if (stmts != null && stmts.size() > 0) {
2767                                                for (int i = 0; i < stmts.size(); i++) {
2768                                                        analyzeCustomSqlStmt(stmts.get(i));
2769                                                }
2770                                        }
2771
2772                                        String dynamicSql = execImmeStmt.getDynamicSQL();
2773                                        if (!SQLUtil.isEmpty(dynamicSql)) {
2774                                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
2775                                                sqlparser.sqltext = dynamicSql;
2776                                                int result = sqlparser.parse();
2777                                                if (result != 0) {
2778                                                        errors = sqlparser.getSyntaxErrors();
2779                                                        if (errors != null && !errors.isEmpty()) {
2780                                                                for (int i = 0; i < errors.size(); i++) {
2781                                                                        TSyntaxError error = errors.get(i);
2782                                                                        ErrorInfo errorInfo = new ErrorInfo();
2783                                                                        errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
2784                                                                        errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
2785                                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2786                                                                                        ModelBindingManager.getGlobalHash()));
2787                                                                        String[] segments = error.tokentext.split("\n");
2788                                                                        if (segments.length == 1) {
2789                                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2790                                                                                                error.columnNo + error.tokentext.length(),
2791                                                                                                ModelBindingManager.getGlobalHash()));
2792                                                                        } else {
2793                                                                                errorInfo.setEndPosition(
2794                                                                                                new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2795                                                                                                                (long) segments[segments.length - 1].length() + 1,
2796                                                                                                                ModelBindingManager.getGlobalHash()));
2797                                                                        }
2798                                                                        errorInfo.fillInfo(this);
2799                                                                        errorInfos.add(errorInfo);
2800                                                                }
2801                                                        }
2802                                                } else if (sqlparser.sqlstatements != null) {
2803                                                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2804                                                                analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
2805                                                        }
2806                                                }
2807                                        }
2808                                }
2809                        } else if (stmt instanceof TCallStatement) {
2810                                TCallStatement callStmt = (TCallStatement)stmt;
2811                                stmtStack.push(stmt);
2812                                analyzeCallStmt(callStmt);
2813                                stmtStack.pop();
2814                        } else if (stmt instanceof TBasicStmt) {
2815                                TBasicStmt oracleBasicStmt = (TBasicStmt) stmt;
2816                                stmtStack.push(stmt);
2817                                analyzeOracleBasicStmt(oracleBasicStmt);
2818                                stmtStack.pop();
2819                        } else if (stmt instanceof TIfStmt) {
2820                                TIfStmt ifStmt = (TIfStmt) stmt;
2821                                stmtStack.push(stmt);
2822                                analyzeIfStmt(ifStmt);
2823                                stmtStack.pop();
2824                        } else if (stmt instanceof TElsifStmt) {
2825                                TElsifStmt elsIfStmt = (TElsifStmt) stmt;
2826                                stmtStack.push(stmt);
2827                                analyzeElsIfStmt(elsIfStmt);
2828                                stmtStack.pop();
2829                        } else if (stmt.getStatements() != null && stmt.getStatements().size() > 0) {
2830                                for (int i = 0; i < stmt.getStatements().size(); i++) {
2831                                        analyzeCustomSqlStmt(stmt.getStatements().get(i));
2832                                }
2833                        } else if (stmt instanceof TCreateIndexSqlStatement) {
2834                                stmtStack.push(stmt);
2835                                analyzeCreateIndexStageStmt((TCreateIndexSqlStatement) stmt);
2836                                stmtStack.pop();
2837                        }
2838                } catch (Exception e) {
2839                        logger.error("analyze sql stmt failed.", e);
2840                        ErrorInfo errorInfo = new ErrorInfo();
2841                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
2842                        if (e.getMessage() == null) {
2843                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
2844                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
2845                                } else {
2846                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
2847                                }
2848                        } else {
2849                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
2850                        }
2851                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
2852                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
2853                        String[] segments = stmt.getEndToken().astext.split("\n", -1);
2854                        if (segments.length == 1) {
2855                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
2856                                                stmt.getEndToken().columnNo + stmt.getEndToken().astext.length(),
2857                                                ModelBindingManager.getGlobalHash()));
2858                        } else {
2859                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo + segments.length - 1,
2860                                                (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash()));
2861                        }
2862                        errorInfo.fillInfo(this);
2863                        errorInfos.add(errorInfo);
2864                }
2865        }
2866
2867        private void analyzePlsqlRecordTypeDefStmt(TPlsqlRecordTypeDefStmt stmt) {
2868                TObjectName typeName = stmt.getTypeName();
2869                Variable variable = modelFactory.createVariable(typeName);
2870                variable.setSubType(SubType.record_type);
2871        
2872                if (stmt.getFieldDeclarations() != null) {
2873                        for (int i = 0; i < stmt.getFieldDeclarations().size(); i++) {
2874                                TParameterDeclaration param = stmt.getFieldDeclarations().getParameterDeclarationItem(i);
2875                                String dataTypeName = param.getDataType().getDataTypeName();
2876                                TObjectName columnName = param.getParameterName();      
2877                                TableColumn variableProperty = modelFactory.createTableColumn(variable, columnName, true);
2878                                if(dataTypeName.indexOf(".")!=-1) {
2879                                        String tableName = dataTypeName.substring(0, dataTypeName.lastIndexOf("."));
2880                                        Table table = modelFactory.createTableByName(tableName, true);
2881                                        if(table!=null) {
2882                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(table, dataTypeName);
2883                                                if (tableColumn != null) {
2884                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
2885                                                        relation.setEffectType(EffectType.rowtype);
2886                                                        relation.setTarget(new TableColumnRelationshipElement(variableProperty));
2887                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
2888                                                }
2889                                        }
2890                                }
2891                        }
2892                        variable.setDetermined(true);
2893                }
2894                else {
2895                        TObjectName starColumn = new TObjectName();
2896                        starColumn.setString("*");
2897                }
2898        }
2899        
2900        private void analyzePlsqlTableTypeDefStmt(TPlsqlTableTypeDefStmt stmt) {
2901                TTypeName typeName = stmt.getElementDataType();
2902                if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) {
2903                        Variable cursorVariable = modelFactory.createVariable(stmt.getTypeName());
2904                        cursorVariable.setSubType(SubType.record_type);
2905
2906                        Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false);
2907                        if(!variableTable.isCreateTable()) {
2908                                TObjectName starColumn1 = new TObjectName();
2909                                starColumn1.setString("*");
2910                                TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true);
2911                                variableTableStarColumn.setShowStar(false);
2912                                variableTableStarColumn.setExpandStar(true);
2913
2914                                TObjectName starColumn = new TObjectName();
2915                                starColumn.setString("*");
2916                                TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
2917                                variableProperty.setShowStar(false);
2918                                variableProperty.setExpandStar(true);
2919
2920                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
2921                                dataflowRelation.setEffectType(EffectType.rowtype);
2922                                dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn));
2923                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
2924                        } else {
2925                                for (TableColumn sourceColumn : variableTable.getColumns()) {
2926                                        String columnName = sourceColumn.getName();
2927                                        TObjectName targetColumn = new TObjectName();
2928                                        targetColumn.setString(columnName);
2929                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true);
2930                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
2931                                        dataflowRelation.setEffectType(EffectType.rowtype);
2932                                        dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn));
2933                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
2934                                }
2935                        }
2936                } 
2937        }
2938
2939        private void analyzeMssqlCreateType(TMssqlCreateType createType) {
2940
2941        }
2942
2943        private void analyzeMssqlExecute(TMssqlExecute executeStmt) {
2944                if (executeStmt.getModuleName() != null) {
2945                        TObjectName module = executeStmt.getModuleName();
2946                        if(module.toString().toLowerCase().endsWith("sp_rename")) {
2947                                String oldTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString());        
2948                                Table oldNameTableModel = modelFactory.createTableByName(oldTableName, true);
2949                                List<String> oldTableNames = SQLUtil.parseNames(oldNameTableModel.getName());
2950                                TObjectName oldStarColumn = new TObjectName();
2951                                oldStarColumn.setString("*");
2952                                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
2953                                
2954                                String newTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(1).toString());
2955                                List<String> newTableNames = SQLUtil.parseNames(newTableName);
2956                                if (oldTableNames.size() > newTableNames.size()) {
2957                                        for (int i = oldTableNames.size() - newTableNames.size() - 1; i >= 0; i--) {
2958                                                newTableName = (oldTableNames.get(i) + ".") + newTableName;
2959                                        }
2960                                }
2961
2962                                Table newNameTableModel = modelFactory.createTableByName(newTableName, true);
2963                                TObjectName newStarColumn = new TObjectName();
2964                                newStarColumn.setString("*");
2965                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true);
2966                                
2967                                Process process = modelFactory.createProcess(executeStmt);
2968                                newNameTableModel.addProcess(process);
2969                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
2970                                relation.setEffectType(EffectType.rename_table);
2971                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
2972                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
2973                                relation.setProcess(process);
2974                                
2975                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
2976                                        oldTableStarColumn.setShowStar(false);
2977                                        relation.setShowStarRelation(false);
2978                                }
2979
2980                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
2981                                        newTableStarColumn.setShowStar(false);
2982                                        relation.setShowStarRelation(false);
2983                                }
2984                        }
2985                        else if(module.toString().toLowerCase().endsWith("sp_executesql")) {
2986                                String sql = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString()); 
2987                                if(sql.startsWith("N")) {
2988                                        sql =  SQLUtil.trimColumnStringQuote(sql.substring(1));
2989                                }
2990                                executeDynamicSql(sql);
2991                        }
2992                        else {
2993                                int argumentSize = executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size();
2994                                String procedureNameWithArgSize = module.toString() + "(" + argumentSize + ")";
2995                                if (argumentSize <= 0  || !DlineageUtil.supportFunctionOverride(option.getVendor())) {
2996                                        procedureNameWithArgSize = module.toString();
2997                                }
2998                                if (procedureDDLMap.containsKey(procedureNameWithArgSize)) {
2999                                        analyzeCustomSqlStmt(procedureDDLMap.get(procedureNameWithArgSize));
3000                                }
3001                                Procedure procedure = modelFactory.createProcedureByName(module, executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size());
3002                                String procedureParent = getProcedureParentName(executeStmt);
3003                                if (procedureParent != null) {
3004                                        Procedure caller = modelManager
3005                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3006                                        if (caller != null) {
3007                                                CallRelationship callRelation = modelFactory.createCallRelation();
3008                                                callRelation.setCallObject(executeStmt);
3009                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3010                                                callRelation.addSource(new ProcedureRelationshipElement(procedure));
3011                                                if(isBuiltInFunctionName(module) || isKeyword(module)){
3012                                                        callRelation.setBuiltIn(true);
3013                                                }
3014                                        }
3015                                }
3016
3017                                if (procedure.getArguments() != null) {
3018                                        for (int i = 0; i < procedure.getArguments().size(); i++) {
3019                                                Argument argument = procedure.getArguments().get(i);
3020                                                Variable variable = modelFactory.createVariable(procedure, argument.getName(), false);
3021                                                if (variable != null) {
3022                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3023                                                                Transform transform = new Transform();
3024                                                                transform.setType(Transform.FUNCTION);
3025                                                                transform.setCode(module);
3026                                                                variable.getColumns().get(0).setTransform(transform);
3027                                                        }
3028                                                        Process process = modelFactory.createProcess(executeStmt);
3029                                                        variable.addProcess(process);
3030                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), executeStmt, argument.getName(), i, process);
3031                                                }
3032                                        }
3033                                }
3034                        }
3035                }
3036        }
3037
3038        private void analyzeDropTableStmt(TDropTableSqlStatement stmt) {
3039                TTable dropTable = stmt.getTargetTable();
3040                if(dropTable == null) {
3041                        return;
3042                }
3043                Table tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(dropTable.getTableName().toString()));
3044                if(tableModel!=null) {
3045                        modelManager.dropTable(tableModel);
3046                }
3047                
3048                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
3049                        tableModel = modelFactory.createTable(dropTable);
3050                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
3051                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
3052                        crudRelationship.setEffectType(EffectType.drop_table);
3053                }
3054        }
3055        
3056        private void analyzeTruncateTableStmt(TTruncateStatement stmt) {
3057                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
3058                        TObjectName table = stmt.getTableName();
3059                        Table tableModel = modelFactory.createTableByName(table);
3060                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
3061                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
3062                        crudRelationship.setEffectType(EffectType.truncate_table);
3063                }
3064        }
3065
3066        private void analyzeCallStmt(TCallStatement callStmt) {
3067                if (callStmt.getRoutineExpr() != null && callStmt.getRoutineExpr().getFunctionCall() != null) {
3068
3069                        TFunctionCall functionCall = callStmt.getRoutineExpr().getFunctionCall();
3070                        Procedure callee = modelManager.getProcedureByName(
3071                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3072                        if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3073                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3074                                callee = modelManager.getProcedureByName(DlineageUtil
3075                                                .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3076                        }
3077                        if (callee != null) {
3078                                String procedureParent = getProcedureParentName(callStmt);
3079                                if (procedureParent != null) {
3080                                        Procedure caller = modelManager
3081                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3082                                        if (caller != null) {
3083                                                CallRelationship callRelation = modelFactory.createCallRelation();
3084                                                callRelation.setCallObject(callStmt);
3085                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3086                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3087                                                if (isBuiltInFunctionName(functionCall.getFunctionName())
3088                                                                || isKeyword(functionCall.getFunctionName())) {
3089                                                        callRelation.setBuiltIn(true);
3090                                                }
3091                                        }
3092                                }
3093                                if (callee.getArguments() != null) {
3094                                        for (int i = 0; i < callee.getArguments().size(); i++) {
3095                                                Argument argument = callee.getArguments().get(i);
3096                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3097                                                if (variable != null) {
3098                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3099                                                                Transform transform = new Transform();
3100                                                                transform.setType(Transform.FUNCTION);
3101                                                                transform.setCode(functionCall);
3102                                                                variable.getColumns().get(0).setTransform(transform);
3103                                                        }
3104                                                        Process process = modelFactory.createProcess(callStmt);
3105                                                        variable.addProcess(process);
3106                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i,
3107                                                                        process);
3108                                                }
3109                                        }
3110                                }
3111                        } else {
3112                                Function function = (Function) createFunction(functionCall);
3113                                String procedureParent = getProcedureParentName(callStmt);
3114                                if (procedureParent != null) {
3115                                        Procedure caller = modelManager
3116                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3117                                        if (caller != null) {
3118                                                CallRelationship callRelation = modelFactory.createCallRelation();
3119                                                callRelation.setCallObject(callStmt);
3120                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3121                                                callRelation.addSource(new FunctionRelationshipElement(function));
3122                                                if (isBuiltInFunctionName(functionCall.getFunctionName())
3123                                                                || isKeyword(functionCall.getFunctionName())) {
3124                                                        callRelation.setBuiltIn(true);
3125                                                }
3126                                        }
3127                                }
3128                        }
3129                }
3130                else if (callStmt.getRoutineName() != null) {
3131                        TObjectName function = callStmt.getRoutineName();
3132                        String functionName = function.toString();
3133                        Procedure callee = modelManager.getProcedureByName(
3134                                        DlineageUtil.getIdentifierNormalTableName(functionName));
3135                        if (callee == null && procedureDDLMap.containsKey(functionName)) {
3136                                analyzeCustomSqlStmt(procedureDDLMap.get(functionName));
3137                                callee = modelManager.getProcedureByName(functionName);
3138                        }
3139                        if (callee != null) {
3140                                String procedureParent = getProcedureParentName(callStmt);
3141                                if (procedureParent != null) {
3142                                        Procedure caller = modelManager
3143                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3144                                        if (caller != null) {
3145                                                CallRelationship callRelation = modelFactory.createCallRelation();
3146                                                callRelation.setCallObject(callStmt);
3147                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3148                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3149                                                if (isBuiltInFunctionName(function)
3150                                                                || isKeyword(function)) {
3151                                                        callRelation.setBuiltIn(true);
3152                                                }
3153                                        }
3154                                }
3155                                if (callee.getArguments() != null) {
3156                                        for (int i = 0; i < callee.getArguments().size(); i++) {
3157                                                Argument argument = callee.getArguments().get(i);
3158                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3159                                                if (variable != null) {
3160                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3161                                                                Transform transform = new Transform();
3162                                                                transform.setType(Transform.FUNCTION);
3163                                                                transform.setCode(callStmt);
3164                                                                variable.getColumns().get(0).setTransform(transform);
3165                                                        }
3166                                                        Process process = modelFactory.createProcess(callStmt);
3167                                                        variable.addProcess(process);
3168                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), callStmt, i,
3169                                                                        process);
3170                                                }
3171                                        }
3172                                }
3173                        }
3174                }
3175        }
3176
3177        private boolean analyzeCustomFunctionCall(TFunctionCall functionCall) {
3178                Procedure callee = modelManager.getProcedureByName(
3179                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3180                if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3181                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3182                        callee = modelManager.getProcedureByName(
3183                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3184                }
3185                if (callee != null) {
3186                        String procedureParent = getProcedureParentName(stmtStack.peek());
3187                        if (procedureParent != null) {
3188                                Procedure caller = modelManager
3189                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3190                                if (caller != null) {
3191                                        CallRelationship callRelation = modelFactory.createCallRelation();
3192                                        callRelation.setCallObject(functionCall);
3193                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3194                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
3195                                        if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3196                                                callRelation.setBuiltIn(true);
3197                                        }
3198                                }
3199                        }
3200                        if (callee.getArguments() != null) {
3201                                for (int i = 0; i < callee.getArguments().size(); i++) {
3202                                        Argument argument = callee.getArguments().get(i);
3203                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3204                                        if(variable!=null) {
3205                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3206                                                        Transform transform = new Transform();
3207                                                        transform.setType(Transform.FUNCTION);
3208                                                        transform.setCode(functionCall);
3209                                                        variable.getColumns().get(0).setTransform(transform);
3210                                                }
3211                                                Process process = modelFactory.createProcess(functionCall);
3212                                                variable.addProcess(process);
3213                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process);
3214                                        }
3215                                }
3216                        }
3217                        return true;
3218                }
3219                return false;
3220        }
3221
3222        private void analyzeOracleBasicStmt(TBasicStmt oracleBasicStmt) {
3223                if (oracleBasicStmt.getExpr() == null || oracleBasicStmt.getExpr().getFunctionCall() == null) {
3224                        return;
3225                }
3226
3227                TFunctionCall functionCall = oracleBasicStmt.getExpr().getFunctionCall();
3228                Procedure callee = modelManager.getProcedureByName(
3229                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3230                if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3231                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3232                        callee = modelManager.getProcedureByName(
3233                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3234                }
3235                if (callee != null) {
3236                        String procedureParent = getProcedureParentName(oracleBasicStmt);
3237                        if (procedureParent != null) {
3238                                Procedure caller = modelManager
3239                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3240                                if (caller != null) {
3241                                        CallRelationship callRelation = modelFactory.createCallRelation();
3242                                        callRelation.setCallObject(functionCall);
3243                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3244                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
3245                                        if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString())
3246                                                        || (isBuiltInFunctionName(functionCall.getFunctionName())
3247                                                        || isKeyword(functionCall.getFunctionName()))) {
3248                                                callRelation.setBuiltIn(true);
3249                                        }
3250                                }
3251                        }
3252                        if (callee.getArguments() != null) {
3253                                for (int i = 0; i < callee.getArguments().size(); i++) {
3254                                        Argument argument = callee.getArguments().get(i);
3255                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3256                                        if(variable!=null) {
3257                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3258                                                        Transform transform = new Transform();
3259                                                        transform.setType(Transform.FUNCTION);
3260                                                        transform.setCode(functionCall);
3261                                                        variable.getColumns().get(0).setTransform(transform);
3262                                                }
3263                                                Process process = modelFactory.createProcess(functionCall);
3264                                                variable.addProcess(process);
3265                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process);
3266                                        }
3267                                }
3268                        }
3269                } else {
3270                        Function function = modelFactory.createFunction(functionCall);
3271                        String procedureParent = getProcedureParentName(oracleBasicStmt);
3272                        if (procedureParent != null) {
3273                                Procedure caller = modelManager
3274                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3275                                if (caller != null) {
3276                                        CallRelationship callRelation = modelFactory.createCallRelation();
3277                                        callRelation.setCallObject(functionCall);
3278                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3279                                        callRelation.addSource(new FunctionRelationshipElement(function));
3280                                        if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString())
3281                                                        || (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName()))) {
3282                                                callRelation.setBuiltIn(true);
3283                                        }
3284                                }
3285                        }
3286                }
3287        }
3288
3289        private void analyzeIfStmt(TIfStmt ifStmt) {
3290                if (ifStmt.getCondition() != null) {
3291                        columnsInExpr visitor = new columnsInExpr();
3292                        ifStmt.getCondition().inOrderTraverse(visitor);
3293                        List<TParseTreeNode> functions = visitor.getFunctions();
3294
3295                        if (functions != null && !functions.isEmpty()) {
3296                                for (int i = 0; i < functions.size(); i++) {
3297                                        if (!(functions.get(i) instanceof TFunctionCall))
3298                                                continue;
3299                                        TFunctionCall functionCall = (TFunctionCall) functions.get(i);
3300                                        Procedure callee = modelManager.getProcedureByName(DlineageUtil
3301                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3302                                        if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3303                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3304                                                callee = modelManager.getProcedureByName(
3305                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3306                                        }
3307                                        if (callee != null) {
3308                                                String procedureParent = getProcedureParentName(ifStmt);
3309                                                if (procedureParent != null) {
3310                                                        Procedure caller = modelManager
3311                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3312                                                        if (caller != null) {
3313                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3314                                                                callRelation.setCallObject(functionCall);
3315                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3316                                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3317                                                                if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) {
3318                                                                        callRelation.setBuiltIn(true);
3319                                                                }
3320                                                        }
3321                                                }
3322                                                if (callee.getArguments() != null) {
3323                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
3324                                                                Argument argument = callee.getArguments().get(j);
3325                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3326                                                                if(variable!=null) {
3327                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3328                                                                                Transform transform = new Transform();
3329                                                                                transform.setType(Transform.FUNCTION);
3330                                                                                transform.setCode(functionCall);
3331                                                                                variable.getColumns().get(0).setTransform(transform);
3332                                                                        }
3333                                                                        Process process = modelFactory.createProcess(functionCall);
3334                                                                        variable.addProcess(process);
3335                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
3336                                                                }
3337                                                        }
3338                                                }
3339                                        } else {
3340                                                Function function = modelFactory.createFunction(functionCall);
3341                                                String procedureParent = getProcedureParentName(ifStmt);
3342                                                if (procedureParent != null) {
3343                                                        Procedure caller = modelManager
3344                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3345                                                        if (caller != null) {
3346                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3347                                                                callRelation.setCallObject(functionCall);
3348                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3349                                                                callRelation.addSource(new FunctionRelationshipElement(function));
3350                                                                if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) {
3351                                                                        callRelation.setBuiltIn(true);
3352                                                                }
3353                                                        }
3354                                                }
3355                                        }
3356                                }
3357                        }
3358                }
3359
3360                if (ifStmt.getThenStatements() != null) {
3361                        for (int i = 0; i < ifStmt.getThenStatements().size(); ++i) {
3362                                analyzeCustomSqlStmt(ifStmt.getThenStatements().get(i));
3363                                ResultSet returnResult = modelFactory.createResultSet(ifStmt.getThenStatements().get(i), false);
3364                                if(returnResult!=null){
3365                                        for(ResultColumn resultColumn: returnResult.getColumns()){
3366                                                analyzeFilterCondition(resultColumn, ifStmt.getCondition(), null, null, EffectType.function);
3367                                        }
3368                                }
3369                        }
3370                }
3371
3372                if (ifStmt.getElseifStatements() != null) {
3373                        for (int i = 0; i < ifStmt.getElseifStatements().size(); ++i) {
3374                                analyzeCustomSqlStmt(ifStmt.getElseifStatements().get(i));
3375                        }
3376                }
3377
3378                if (ifStmt.getElseStatements() != null) {
3379                        for (int i = 0; i < ifStmt.getElseStatements().size(); ++i) {
3380                                analyzeCustomSqlStmt(ifStmt.getElseStatements().get(i));
3381                        }
3382                }
3383        }
3384
3385        private void analyzeElsIfStmt(TElsifStmt elsIfStmt) {
3386                if (elsIfStmt.getCondition() != null) {
3387                        columnsInExpr visitor = new columnsInExpr();
3388                        elsIfStmt.getCondition().inOrderTraverse(visitor);
3389                        List<TParseTreeNode> functions = visitor.getFunctions();
3390
3391                        if (functions != null && !functions.isEmpty()) {
3392                                for (int i = 0; i < functions.size(); i++) {
3393                                        if (!(functions.get(i) instanceof TFunctionCall))
3394                                                continue;
3395                                        TFunctionCall functionCall = (TFunctionCall) functions.get(i);
3396                                        Procedure callee = modelManager.getProcedureByName(DlineageUtil
3397                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3398                                        if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3399                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3400                                                callee = modelManager.getProcedureByName(
3401                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3402                                        }
3403                                        if (callee != null) {
3404                                                String procedureParent = getProcedureParentName(elsIfStmt);
3405                                                if (procedureParent != null) {
3406                                                        Procedure caller = modelManager
3407                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3408                                                        if (caller != null) {
3409                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3410                                                                callRelation.setCallObject(functionCall);
3411                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3412                                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3413                                                                if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3414                                                                        callRelation.setBuiltIn(true);
3415                                                                }
3416                                                        }
3417                                                }
3418                                                if (callee.getArguments() != null) {
3419                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
3420                                                                Argument argument = callee.getArguments().get(j);
3421                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3422                                                                if(variable!=null) {
3423                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3424                                                                                Transform transform = new Transform();
3425                                                                                transform.setType(Transform.FUNCTION);
3426                                                                                transform.setCode(functionCall);
3427                                                                                variable.getColumns().get(0).setTransform(transform);
3428                                                                        }
3429                                                                        Process process = modelFactory.createProcess(functionCall);
3430                                                                        variable.addProcess(process);
3431                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
3432                                                                }
3433                                                        }
3434                                                }
3435                                        } else {
3436                                                Function function = modelFactory.createFunction(functionCall);
3437                                                String procedureParent = getProcedureParentName(elsIfStmt);
3438                                                if (procedureParent != null) {
3439                                                        Procedure caller = modelManager
3440                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3441                                                        if (caller != null) {
3442                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3443                                                                callRelation.setCallObject(functionCall);
3444                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3445                                                                callRelation.addSource(new FunctionRelationshipElement(function));
3446                                                                if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3447                                                                        callRelation.setBuiltIn(true);
3448                                                                }
3449                                                        }
3450                                                }
3451                                        }
3452                                }
3453                        }
3454                }
3455
3456                if (elsIfStmt.getThenStatements() != null) {
3457                        for (int i = 0; i < elsIfStmt.getThenStatements().size(); ++i) {
3458                                ResultSet returnResult = modelFactory.createResultSet(elsIfStmt.getThenStatements().get(i), false);
3459                                if (returnResult != null) {
3460                                        for (ResultColumn resultColumn : returnResult.getColumns()) {
3461                                                analyzeFilterCondition(resultColumn, elsIfStmt.getCondition(), null, null, EffectType.function);
3462                                        }
3463                                }
3464                                analyzeCustomSqlStmt(elsIfStmt.getThenStatements().get(i));
3465                        }
3466                }
3467        }
3468
3469        private void analyzeCloneTableStmt(TCreateTableSqlStatement stmt) {
3470                if (stmt.getCloneSourceTable() != null) {
3471                        Table sourceTable = modelFactory.createTableByName(stmt.getCloneSourceTable());
3472                        Table cloneTable = modelFactory.createTableByName(stmt.getTableName());
3473                        Process process = modelFactory.createProcess(stmt);
3474                        cloneTable.addProcess(process);
3475
3476                        if (sourceTable.isDetermined()) {
3477                                for (int k = 0; k < sourceTable.getColumns().size(); k++) {
3478                                        TableColumn sourceColumn = sourceTable.getColumns().get(k);
3479                                        TObjectName objectName = new TObjectName();
3480                                        objectName.setString(sourceColumn.getName());
3481                                        TableColumn tableColumn = modelFactory.createTableColumn(cloneTable, objectName, true);
3482                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3483                                        dataflowRelation.setEffectType(EffectType.clone_table);
3484                                        dataflowRelation
3485                                                        .addSource(new TableColumnRelationshipElement(sourceColumn));
3486                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
3487                                        dataflowRelation.setProcess(process);
3488                                }
3489                                cloneTable.setDetermined(true);
3490                                cloneTable.setFromDDL(true);
3491                        } else {
3492                                TObjectName sourceName = new TObjectName();
3493                                sourceName.setString("*");
3494                                TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceName, false);
3495                                TObjectName targetName = new TObjectName();
3496                                targetName.setString("*");
3497                                TableColumn targetTableColumn = modelFactory.createTableColumn(cloneTable, targetName, false);
3498                                if(sourceTableColumn!=null && targetTableColumn!=null) {
3499                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3500                                        dataflowRelation.setEffectType(EffectType.clone_table);
3501                                        dataflowRelation
3502                                                        .addSource(new TableColumnRelationshipElement(sourceTableColumn));
3503                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
3504                                        dataflowRelation.setProcess(process);
3505                                }
3506                        }
3507                }
3508        }
3509
3510        private void analyzeCloneDatabaseStmt(TCreateDatabaseSqlStatement stmt) {
3511                if (stmt.getCloneSourceDb() != null) {
3512                        Database sourceDatabase = modelFactory.createDatabase(stmt.getCloneSourceDb());
3513                        Database cloneDatabase = modelFactory.createDatabase(stmt.getDatabaseName());
3514                        Process process = modelFactory.createProcess(stmt);
3515                        cloneDatabase.addProcess(process);
3516                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3517                        relation.setEffectType(EffectType.clone_database);
3518                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneDatabase.getRelationRows()));
3519                        relation.addSource(
3520                                        new RelationRowsRelationshipElement<TableRelationRows>(sourceDatabase.getRelationRows()));
3521                        relation.setProcess(process);
3522                }
3523        }
3524
3525        private void analyzeCloneSchemaStmt(TCreateSchemaSqlStatement stmt) {
3526                if (stmt.getCloneSourceSchema() != null) {
3527                        Schema sourceSchema = modelFactory.createSchema(stmt.getCloneSourceSchema());
3528                        Schema cloneSchema = modelFactory.createSchema(stmt.getSchemaName());
3529                        Process process = modelFactory.createProcess(stmt);
3530                        cloneSchema.addProcess(process);
3531                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3532                        relation.setEffectType(EffectType.clone_schema);
3533                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneSchema.getRelationRows()));
3534                        relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(sourceSchema.getRelationRows()));
3535                        relation.setProcess(process);
3536                }
3537        }
3538
3539        private void executeDynamicSql(String sql) {
3540                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3541                sqlparser.sqltext = sql;
3542                int result = sqlparser.parse();
3543                if (result == 0) {
3544                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3545                                analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3546                        }
3547                }
3548        }
3549
3550        private void extractSnowflakeSQLFromProcedure(TCreateProcedureStmt procedure) {
3551                Map<String, String> argMap = new LinkedHashMap<String, String>();
3552                if (procedure.getParameterDeclarations() != null) {
3553                        for (int i = 0; i < procedure.getParameterDeclarations().size(); i++) {
3554                                TParameterDeclaration def = procedure.getParameterDeclarations().getParameterDeclarationItem(i);
3555                                argMap.put(def.getParameterName().toString(), def.getDataType().getDataTypeName());
3556                        }
3557                }
3558                StringBuilder buffer = new StringBuilder();
3559                buffer.append("(function(");
3560                String[] args = argMap.keySet().toArray(new String[0]);
3561                for (int i = 0; i < args.length; i++) {
3562                        buffer.append(args[i].toUpperCase());
3563                        if (i < args.length - 1) {
3564                                buffer.append(",");
3565                        }
3566                }
3567                buffer.append("){\n");
3568
3569                int start = -1;
3570                int end = -1;
3571                boolean dollar = false;
3572                boolean quote = false;
3573                if (procedure.getRoutineBody().indexOf("$$") != -1) {
3574                        start = procedure.getRoutineBody().indexOf("$$") + 2;
3575                        end = procedure.getRoutineBody().lastIndexOf("$$") - 1;
3576                        dollar = true;
3577                } else if (procedure.getRoutineBody().indexOf("'") != -1) {
3578                        start = procedure.getRoutineBody().indexOf("'") + 1;
3579                        end = procedure.getRoutineBody().lastIndexOf("'");
3580                        quote = true;
3581                }
3582                String body = procedure.getRoutineBody().substring(start, end);
3583                if (dollar && body.indexOf("`") != -1) {
3584                        Pattern pattern = Pattern.compile("`.+?`", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
3585                        Matcher matcher = pattern.matcher(body);
3586                        StringBuffer replaceBuffer = new StringBuffer();
3587                        while (matcher.find()) {
3588                                String condition = matcher.group().replace("\r\n", "\n").replace("'", "\\\\'")
3589                                                .replace("\n", "\\\\n'\n+'").replace("`", "'").replace("$", "RDS_CHAR_DOLLAR");
3590                                matcher.appendReplacement(replaceBuffer, condition);
3591                        }
3592                        matcher.appendTail(replaceBuffer);
3593                        body = replaceBuffer.toString().replace("RDS_CHAR_DOLLAR", "$");
3594                }
3595                if (quote && body.indexOf("'") != -1) {
3596                        body = body.replace("''", "'");
3597                }
3598                buffer.append(body);
3599                buffer.append("})(");
3600                for (int i = 0; i < args.length; i++) {
3601                        String type = argMap.get(args[i]);
3602                        if (type.equalsIgnoreCase("VARCHAR")) {
3603                                buffer.append("'pseudo'");
3604                        } else if (type.equalsIgnoreCase("STRING")) {
3605                                buffer.append("'pseudo'");
3606                        } else if (type.equalsIgnoreCase("CHAR")) {
3607                                buffer.append("'pseudo'");
3608                        } else if (type.equalsIgnoreCase("CHARACTER")) {
3609                                buffer.append("'pseudo'");
3610                        } else if (type.equalsIgnoreCase("TEXT")) {
3611                                buffer.append("'pseudo'");
3612                        } else if (type.equalsIgnoreCase("BINARY")) {
3613                                buffer.append("'pseudo'");
3614                        } else if (type.equalsIgnoreCase("VARBINARY")) {
3615                                buffer.append("'pseudo'");
3616                        } else if (type.equalsIgnoreCase("BOOLEAN")) {
3617                                buffer.append(true);
3618                        } else if (type.equalsIgnoreCase("FLOAT")) {
3619                                buffer.append("1.0");
3620                        } else if (type.equalsIgnoreCase("FLOAT4")) {
3621                                buffer.append("1.0");
3622                        } else if (type.equalsIgnoreCase("FLOAT8")) {
3623                                buffer.append("1.0");
3624                        } else if (type.equalsIgnoreCase("DOUBLE")) {
3625                                buffer.append("1.0");
3626                        } else if (type.equalsIgnoreCase("DOUBLE PRECISION")) {
3627                                buffer.append("1.0");
3628                        } else if (type.equalsIgnoreCase("REAL")) {
3629                                buffer.append("1.0");
3630                        } else if (type.equalsIgnoreCase("NUMBER")) {
3631                                buffer.append("1.0");
3632                        } else if (type.equalsIgnoreCase("DECIMAL")) {
3633                                buffer.append("1.0");
3634                        } else if (type.equalsIgnoreCase("NUMERIC")) {
3635                                buffer.append("1.0");
3636                        } else if (type.equalsIgnoreCase("INT")) {
3637                                buffer.append("1");
3638                        } else if (type.equalsIgnoreCase("INTEGER")) {
3639                                buffer.append("1");
3640                        } else if (type.equalsIgnoreCase("BIGINT")) {
3641                                buffer.append("1");
3642                        } else if (type.equalsIgnoreCase("SMALLINT")) {
3643                                buffer.append("1");
3644                        } else if (type.equalsIgnoreCase("DATE")) {
3645                                buffer.append("new Date()");
3646                        } else if (type.equalsIgnoreCase("DATETIME")) {
3647                                buffer.append("new Date()");
3648                        } else if (type.equalsIgnoreCase("TIME")) {
3649                                buffer.append("new Date()");
3650                        } else if (type.equalsIgnoreCase("TIMESTAMP")) {
3651                                buffer.append("new Date()");
3652                        } else if (type.equalsIgnoreCase("TIMESTAMP_LTZ")) {
3653                                buffer.append("new Date()");
3654                        } else if (type.equalsIgnoreCase("TIMESTAMP_NTZ")) {
3655                                buffer.append("new Date()");
3656                        } else if (type.equalsIgnoreCase("TIMESTAMP_TZ")) {
3657                                buffer.append("new Date()");
3658                        } else if (type.equalsIgnoreCase("VARIANT")) {
3659                                buffer.append("{}");
3660                        } else if (type.equalsIgnoreCase("OBJECT")) {
3661                                buffer.append("{}");
3662                        } else if (type.equalsIgnoreCase("ARRAY")) {
3663                                buffer.append("[]");
3664                        } else if (type.equalsIgnoreCase("GEOGRAPHY")) {
3665                                buffer.append("{}");
3666                        }
3667                        if (i < args.length - 1) {
3668                                buffer.append(",");
3669                        }
3670                }
3671                buffer.append(");");
3672
3673                try {
3674                        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
3675                        ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
3676                        nashorn.put("analyzer", this);
3677                        nashorn.eval(new InputStreamReader(
3678                                        getClass().getResourceAsStream("/gudusoft/gsqlparser/parser/snowflake/snowflake.js")));
3679                        nashorn.eval(new StringReader(buffer.toString()));
3680                } catch (ScriptException e) {
3681                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3682                        sqlparser.sqltext = body;
3683                        int result = sqlparser.parse();
3684                        if (result == 0) {
3685                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3686                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3687                                }
3688                                return;
3689                        }
3690                        ErrorInfo errorInfo = new ErrorInfo();
3691                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
3692                        errorInfo.setErrorMessage("Invoke script error: " + e.getMessage());
3693                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(procedure.getStartToken().lineNo,
3694                                        procedure.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
3695                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(procedure.getEndToken().lineNo,
3696                                        procedure.getEndToken().columnNo + procedure.getEndToken().astext.length(),
3697                                        ModelBindingManager.getGlobalHash()));
3698                        errorInfos.add(errorInfo);
3699                }
3700        }
3701
3702        private void analyzeHiveLoadStmt(THiveLoad stmt) {
3703                if (stmt.getPath() != null && stmt.getTable() != null) {
3704                        Table uriFile = modelFactory.createTableByName(stmt.getPath(), true);
3705                        uriFile.setPath(true);
3706                        uriFile.setCreateTable(true);
3707                        TObjectName fileUri = new TObjectName();
3708                        fileUri.setString("uri=" + stmt.getPath());
3709                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
3710
3711                        Table tableModel = modelFactory.createTable(stmt.getTable());
3712                        Process process = modelFactory.createProcess(stmt);
3713                        tableModel.addProcess(process);
3714
3715                        TPartitionExtensionClause p = stmt.getTable().getPartitionExtensionClause();
3716                        if (p.getKeyValues() != null && p.getKeyValues().size() > 0) {
3717                                for (int i = 0; i < p.getKeyValues().size(); i++) {
3718                                        TExpression expression = p.getKeyValues().getExpression(i);
3719                                        if (expression.getLeftOperand().getExpressionType() == EExpressionType.simple_object_name_t) {
3720                                                modelFactory.createTableColumn(tableModel, expression.getLeftOperand().getObjectOperand(),
3721                                                                true);
3722                                        }
3723                                }
3724                        }
3725
3726                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
3727                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3728                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
3729                                relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
3730                                relation.setProcess(process);
3731                        }
3732                }
3733        }
3734        
3735        private void analyzeLoadDataStmt(TLoadDataStmt stmt) {
3736                
3737        }
3738
3739        private void analyzeUnloadStmt(TUnloadStmt unloadStmt) {
3740                if (unloadStmt.getSelectSqlStatement() != null && unloadStmt.getS3() != null) {
3741
3742                        Table uriFile = modelFactory.createTableByName(unloadStmt.getS3(), true);
3743                        uriFile.setPath(true);
3744                        uriFile.setCreateTable(true);
3745                        TObjectName fileUri = new TObjectName();
3746                        fileUri.setString("uri=" + unloadStmt.getS3());
3747                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
3748
3749                        Process process = modelFactory.createProcess(unloadStmt);
3750                        uriFile.addProcess(process);
3751
3752                        TCustomSqlStatement stmt = unloadStmt.getSelectSqlStatement();
3753                        analyzeCustomSqlStmt(stmt);
3754                        if (stmt instanceof TSelectSqlStatement) {
3755                                TSelectSqlStatement select = (TSelectSqlStatement) stmt;
3756                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(select);
3757                                if (resultSetModel != null) {
3758                                        for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
3759                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
3760                                                if (resultColumn.hasStarLinkColumn()
3761                                                                && resultColumn.getStarLinkColumnNames().size() > 0) {
3762                                                        for (int k = 0; k < resultColumn.getStarLinkColumnNames().size(); k++) {
3763                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(resultSetModel,
3764                                                                                resultColumn.getStarLinkColumnName(k), false);
3765                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3766                                                                dataflowRelation.setEffectType(EffectType.unload);
3767                                                                dataflowRelation
3768                                                                                .addSource(new ResultColumnRelationshipElement(expandStarColumn));
3769                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn));
3770                                                                dataflowRelation.setProcess(process);
3771                                                        }
3772                                                }
3773                                                if (!resultColumn.hasStarLinkColumn() || resultColumn.isShowStar()) {
3774                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3775                                                        dataflowRelation.setEffectType(EffectType.unload);
3776                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
3777                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn));
3778                                                        dataflowRelation.setProcess(process);
3779                                                }
3780                                        }
3781                                }
3782                        }
3783                }
3784
3785        }
3786
3787        private void analyzeCopyIntoStmt(TSnowflakeCopyIntoStmt stmt) {
3788                if (stmt.getTableName() != null) {
3789                        if (stmt.getStageLocation() != null) {
3790                                Table intoTable = modelManager
3791                                                .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
3792                                if (intoTable == null) {
3793                                        intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
3794                                        TObjectName starColumn = new TObjectName();
3795                                        starColumn.setString("*");
3796                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
3797                                        if (column != null) {
3798                                                column.setExpandStar(false);
3799                                                column.setPseduo(true);
3800                                        }
3801                                }
3802                                Process process = modelFactory.createProcess(stmt);
3803                                intoTable.addProcess(process);
3804
3805                                TObjectName stageName = stmt.getStageLocation().getStageName();
3806                                if (stageName == null || stmt.getStageLocation().getTableName() != null) {
3807                                        stageName = stmt.getStageLocation().getTableName();
3808                                }
3809                                if (stageName != null) {
3810                                        String stageFullName = DlineageUtil.getTableFullName(stageName.toString());
3811                                        Table stage = modelManager.getTableByName(stageFullName);
3812                                        if (stage == null) {
3813                                                stage = modelFactory.createStage(stageName);
3814                                                stage.setCreateTable(true);
3815                                                stage.setStage(true);
3816                                                if (stmt.getStageLocation().getPath() != null) {
3817                                                        stage.setLocation(stmt.getStageLocation().getPath().toString());
3818                                                        TObjectName location = new TObjectName();
3819                                                        location.setString(stmt.getStageLocation().getPath().toString());
3820                                                        modelFactory.createStageLocation(stage, location);
3821                                                } else {
3822                                                        stage.setLocation("unknownPath");
3823                                                        TObjectName location = new TObjectName();
3824                                                        location.setString("unknownPath");
3825                                                        modelFactory.createStageLocation(stage, location);
3826                                                }
3827                                        }
3828
3829                                        if (stage != null && intoTable != null) {
3830                                                if (intoTable != null && !intoTable.getColumns().isEmpty() && !stage.getColumns().isEmpty()) {
3831                                                        for (int i = 0; i < intoTable.getColumns().size(); i++) {
3832                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3833                                                                relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
3834                                                                relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
3835                                                                relation.setProcess(process);
3836                                                        }
3837                                                }
3838                                        }
3839                                } else if (stmt.getStageLocation().getExternalLocation() != null) {
3840                                        Table pathModel = modelFactory.createTableByName(stmt.getStageLocation().getExternalLocation(),
3841                                                        true);
3842                                        pathModel.setPath(true);
3843                                        pathModel.setCreateTable(true);
3844                                        TableColumn fileUriColumn = modelFactory.createFileUri(pathModel,
3845                                                        stmt.getStageLocation().getExternalLocation());
3846                                        if (intoTable != null) {
3847                                                if (intoTable != null && !intoTable.getColumns().isEmpty()) {
3848                                                        for (int i = 0; i < intoTable.getColumns().size(); i++) {
3849                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3850                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
3851                                                                relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
3852                                                                relation.setProcess(process);
3853                                                        }
3854                                                }
3855                                        }
3856                                }
3857                        }
3858                        else if (stmt.getSubQuery() != null) {
3859                                analyzeSelectStmt(stmt.getSubQuery());
3860                                
3861                                Table intoTable = modelManager
3862                                                .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
3863                                if (intoTable == null) {
3864                                        intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
3865                                        TObjectName starColumn = new TObjectName();
3866                                        starColumn.setString("*");
3867                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
3868                                        column.setExpandStar(true);
3869                                        column.setPseduo(true);
3870                                        
3871                                        Process process = modelFactory.createProcess(stmt);
3872                                        intoTable.addProcess(process);
3873                                        
3874                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
3875                                        if (resultSetModel != null) {
3876                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
3877                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
3878                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3879                                                        dataflowRelation.setEffectType(EffectType.copy);
3880                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
3881                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(column));
3882                                                }
3883                                        }
3884                                }
3885                        }
3886                }
3887        }
3888
3889        private void analyzeRedshiftCopyStmt(TRedshiftCopy stmt) {
3890                if (stmt.getTableName() != null && stmt.getFromSource() != null) {
3891
3892                        Table intoTable = modelManager
3893                                        .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
3894                        if (intoTable == null) {
3895                                intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
3896                                if (stmt.getColumnList() == null || stmt.getColumnList().size() == 0) {
3897                                        TObjectName starColumn = new TObjectName();
3898                                        starColumn.setString("*");
3899                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
3900                                        if (column != null) {
3901                                                column.setExpandStar(false);
3902                                                column.setPseduo(true);
3903                                        }
3904                                } else {
3905                                        for (TObjectName columnName : stmt.getColumnList()) {
3906                                                modelFactory.createTableColumn(intoTable, columnName, true);
3907                                        }
3908                                }
3909                        }
3910                        Process process = modelFactory.createProcess(stmt);
3911                        intoTable.addProcess(process);
3912
3913                        if (stmt.getFromSource() != null) {
3914                                Table pathModel = modelFactory.createTableByName(stmt.getFromSource(), true);
3915                                pathModel.setPath(true);
3916                                pathModel.setCreateTable(true);
3917                                TObjectName fileUri = new TObjectName();
3918                                fileUri.setString(stmt.getFromSource());
3919                                TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri);
3920                                if (intoTable != null) {
3921                                        if (intoTable != null && !intoTable.getColumns().isEmpty()) {
3922                                                for (int i = 0; i < intoTable.getColumns().size(); i++) {
3923                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3924                                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
3925                                                        relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
3926                                                        relation.setProcess(process);
3927                                                }
3928                                        }
3929                                }
3930                        }
3931                }
3932        }
3933
3934        private void analyzeCreateIndexExpressionOperand(TExpression expr, Table tableModel){
3935                if(expr != null){
3936                        TObjectName columnObj = expr.getObjectOperand();
3937                        if(columnObj!=null){
3938                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, columnObj, true);
3939                                tableConstraint.setIndexKey(true);
3940                        }
3941                        else{
3942                                if(expr.getLeftOperand() != null){
3943                                        analyzeCreateIndexExpressionOperand(expr.getLeftOperand(), tableModel);
3944                                }
3945                                if(expr.getRightOperand() != null){
3946                                        analyzeCreateIndexExpressionOperand(expr.getRightOperand(), tableModel);
3947                                }
3948                        }
3949                }
3950
3951        }
3952        private void analyzeCreateIndexStageStmt(TCreateIndexSqlStatement stmt) {
3953                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
3954                TOrderByItemList columns = stmt.getColumnNameList();
3955                for(int i=0; i< columns.size(); i++){
3956                        TExpression expr = columns.getOrderByItem(i).getSortKey();
3957                        analyzeCreateIndexExpressionOperand(expr, tableModel);
3958                }
3959        }
3960
3961        private void analyzeCreateSynonymStmt(TCreateSynonymStmt stmt) {
3962                TObjectName sourceTableName = stmt.getForName();
3963                if(sourceTableName == null) {
3964                        return;
3965                }
3966                TCustomSqlStatement createView = viewDDLMap
3967                                .get(DlineageUtil.getTableFullName(sourceTableName.toString()));
3968                if (createView != null) {
3969                        analyzeCustomSqlStmt(createView);
3970                }
3971                Table sourceTableModel = modelFactory.createTableByName(sourceTableName);
3972                Process process = modelFactory.createProcess(stmt);
3973                sourceTableModel.addProcess(process);
3974                if(stmt.getSynonymName()!=null) {
3975                        Table synonymTableModel = modelFactory.createTableByName(stmt.getSynonymName());
3976                        synonymTableModel.setSubType(SubType.synonym);
3977                        if(sourceTableModel.isCreateTable()) {
3978                                synonymTableModel.setCreateTable(true);
3979                                for(TableColumn sourceTableColumn: sourceTableModel.getColumns()) {
3980                                        TObjectName columnName = new TObjectName();
3981                                        columnName.setString(sourceTableColumn.getName());
3982                                        TableColumn synonymTableColumn = new TableColumn(synonymTableModel, columnName);
3983                                        synonymTableModel.addColumn(synonymTableColumn);
3984                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3985                                        relation.setEffectType(EffectType.create_synonym);
3986                                        relation.setTarget(new TableColumnRelationshipElement(synonymTableColumn));
3987                                        relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
3988                                        relation.setProcess(process);
3989                                }
3990                        }
3991                        else {
3992                                TObjectName synonymStarColumn = new TObjectName();
3993                                synonymStarColumn.setString("*");
3994                                TableColumn synonymTableStarColumn = modelFactory.createTableColumn(synonymTableModel,
3995                                                synonymStarColumn, true);
3996                                TObjectName sourceStarColumn = new TObjectName();
3997                                sourceStarColumn.setString("*");
3998                                TableColumn sourceTableStarColumn = modelFactory.createTableColumn(sourceTableModel, sourceStarColumn, true);
3999                                
4000                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4001                                relation.setEffectType(EffectType.create_synonym);
4002                                relation.setTarget(new TableColumnRelationshipElement(synonymTableStarColumn));
4003                                relation.addSource(new TableColumnRelationshipElement(sourceTableStarColumn));
4004                                relation.setProcess(process);
4005                        }
4006                }
4007        }
4008        
4009        private void analyzeRenameStmt(TRenameStmt stmt) {
4010                TObjectName oldTableName = stmt.getOldName();
4011                TObjectName newTableName = stmt.getNewName();
4012                
4013                Table oldNameTableModel = modelFactory.createTableByName(oldTableName);
4014                TObjectName oldStarColumn = new TObjectName();
4015                oldStarColumn.setString("*");
4016                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
4017                
4018                Table newNameTableModel = modelFactory.createTableByName(newTableName);
4019                TObjectName newStarColumn = new TObjectName();
4020                newStarColumn.setString("*");
4021                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true);
4022                
4023                Process process = modelFactory.createProcess(stmt);
4024                newNameTableModel.addProcess(process);
4025                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4026                relation.setEffectType( EffectType.rename_table);
4027                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4028                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4029                relation.setProcess(process);
4030                
4031                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4032                        oldTableStarColumn.setShowStar(false);
4033                        relation.setShowStarRelation(false);
4034                }
4035
4036                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4037                        newTableStarColumn.setShowStar(false);
4038                        relation.setShowStarRelation(false);
4039                }
4040        }
4041        
4042        private void analyzeAlterTableStmt(TAlterTableStatement stmt) {
4043                TTable oldNameTable = stmt.getTargetTable();
4044                if (oldNameTable == null) {
4045                        return;
4046                }
4047
4048                Table oldNameTableModel = modelFactory.createTable(oldNameTable);
4049                TObjectName oldStarColumn = new TObjectName();
4050                oldStarColumn.setString("*");
4051                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
4052
4053                for (int i = 0; stmt.getAlterTableOptionList() != null && i < stmt.getAlterTableOptionList().size(); i++) {
4054                        TAlterTableOption option = stmt.getAlterTableOptionList().getAlterTableOption(i);
4055                        if (option.getOptionType() == EAlterTableOptionType.RenameTable
4056                                        || option.getOptionType() == EAlterTableOptionType.swapWith) {
4057                                TObjectName newTableName = option.getNewTableName();
4058                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4059                                boolean containsTable = false;
4060                                for (int j = 0; j < list.size(); j++) {
4061                                        if (list.get(j) instanceof TTable) {
4062                                                TTable newTableTable = (TTable) list.get(j);
4063                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4064                                                newNameTableModel.setStarStmt("rename_table");
4065
4066                                                TObjectName newStarColumn = new TObjectName();
4067                                                newStarColumn.setString("*");
4068                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4069                                                                newStarColumn, true);
4070
4071                                                Process process = modelFactory.createProcess(stmt);
4072                                                newNameTableModel.addProcess(process);
4073                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4074                                                relation.setEffectType(
4075                                                                option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table
4076                                                                                : EffectType.swap_table);                                               
4077                                                if (option.getOptionType() == EAlterTableOptionType.RenameTable) {
4078                                                        relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4079                                                        relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4080                                                } else if (option.getOptionType() == EAlterTableOptionType.swapWith) {
4081                                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4082                                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4083                                                }
4084                                                relation.setProcess(process);
4085                                                containsTable = true;
4086
4087                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4088                                                        oldTableStarColumn.setShowStar(false);
4089                                                        relation.setShowStarRelation(false);
4090                                                }
4091
4092                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4093                                                        newTableStarColumn.setShowStar(false);
4094                                                        relation.setShowStarRelation(false);
4095                                                }
4096                                        }
4097                                }
4098                                if (!containsTable) {
4099                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4100                                        newNameTableModel.setStarStmt("rename_table");
4101                                        TObjectName newStarColumn = new TObjectName();
4102                                        newStarColumn.setString("*");
4103                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4104                                                        true);
4105
4106                                        Process process = modelFactory.createProcess(stmt);
4107                                        newNameTableModel.addProcess(process);
4108                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4109                                        relation.setEffectType(
4110                                                        option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table
4111                                                                        : EffectType.swap_table);
4112                                        if (option.getOptionType() == EAlterTableOptionType.RenameTable) {
4113                                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4114                                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4115                                        } else if (option.getOptionType() == EAlterTableOptionType.swapWith) {
4116                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4117                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4118                                        }
4119                                        relation.setProcess(process);
4120                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4121                                                oldTableStarColumn.setShowStar(false);
4122                                                relation.setShowStarRelation(false);
4123                                        }
4124
4125                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4126                                                newTableStarColumn.setShowStar(false);
4127                                                relation.setShowStarRelation(false);
4128                                        }
4129
4130                                }
4131                        }
4132                        else if (option.getOptionType() == EAlterTableOptionType.appendFrom) {
4133                                TObjectName newTableName = option.getSourceTableName();
4134                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4135                                boolean containsTable = false;
4136                                for (int j = 0; j < list.size(); j++) {
4137                                        if (list.get(j) instanceof TTable) {
4138                                                TTable newTableTable = (TTable) list.get(j);
4139                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4140                                                newNameTableModel.setStarStmt("append_from");
4141
4142                                                TObjectName newStarColumn = new TObjectName();
4143                                                newStarColumn.setString("*");
4144                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4145                                                                newStarColumn, true);
4146
4147                                                Process process = modelFactory.createProcess(stmt);
4148                                                newNameTableModel.addProcess(process);
4149                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4150                                                relation.setEffectType(EffectType.append_from);
4151                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4152                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4153                                                relation.setProcess(process);
4154                                                containsTable = true;
4155
4156                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4157                                                        oldTableStarColumn.setShowStar(false);
4158                                                        relation.setShowStarRelation(false);
4159                                                }
4160
4161                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4162                                                        newTableStarColumn.setShowStar(false);
4163                                                        relation.setShowStarRelation(false);
4164                                                }
4165                                        }
4166                                }
4167                                if (!containsTable) {
4168                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4169                                        newNameTableModel.setStarStmt("append_from");
4170                                        TObjectName newStarColumn = new TObjectName();
4171                                        newStarColumn.setString("*");
4172                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4173                                                        true);
4174
4175                                        Process process = modelFactory.createProcess(stmt);
4176                                        newNameTableModel.addProcess(process);
4177                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4178                                        relation.setEffectType(EffectType.append_from);
4179                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4180                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4181                                        relation.setProcess(process);
4182                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4183                                                oldTableStarColumn.setShowStar(false);
4184                                                relation.setShowStarRelation(false);
4185                                        }
4186
4187                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4188                                                newTableStarColumn.setShowStar(false);
4189                                                relation.setShowStarRelation(false);
4190                                        }
4191
4192                                }
4193                        }
4194                        else if (option.getOptionType() == EAlterTableOptionType.exchangePartition) {
4195                                TObjectName newTableName = option.getNewTableName();
4196                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4197                                boolean containsTable = false;
4198                                for (int j = 0; j < list.size(); j++) {
4199                                        if (list.get(j) instanceof TTable) {
4200                                                TTable newTableTable = (TTable) list.get(j);
4201                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4202                                                newNameTableModel.setStarStmt("exchange_partition");
4203
4204                                                TObjectName newStarColumn = new TObjectName();
4205                                                newStarColumn.setString("*");
4206                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4207                                                                newStarColumn, true);
4208
4209                                                Process process = modelFactory.createProcess(stmt);
4210                                                newNameTableModel.addProcess(process);
4211                                                {
4212                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4213                                                        relation.setEffectType(EffectType.exchange_partition);
4214                                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4215                                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4216                                                        relation.setProcess(process);
4217                                                        if (option.getPartitionName() != null) {
4218                                                                relation.setPartition(option.getPartitionName().toString());
4219                                                        }
4220                                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4221                                                                oldTableStarColumn.setShowStar(false);
4222                                                                relation.setShowStarRelation(false);
4223                                                        }
4224
4225                                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4226                                                                newTableStarColumn.setShowStar(false);
4227                                                                relation.setShowStarRelation(false);
4228                                                        }
4229                                                }
4230                                                {
4231                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4232                                                        relation.setEffectType(EffectType.exchange_partition);
4233                                                        relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4234                                                        relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4235                                                        relation.setProcess(process);
4236                                                        if (option.getPartitionName() != null) {
4237                                                                relation.setPartition(option.getPartitionName().toString());
4238                                                        }
4239                                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4240                                                                oldTableStarColumn.setShowStar(false);
4241                                                                relation.setShowStarRelation(false);
4242                                                        }
4243
4244                                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4245                                                                newTableStarColumn.setShowStar(false);
4246                                                                relation.setShowStarRelation(false);
4247                                                        }
4248                                                }
4249                                                containsTable = true;   
4250                                        }
4251                                }
4252                                if (!containsTable) {
4253                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4254                                        newNameTableModel.setStarStmt("exchange_partition");
4255                                        TObjectName newStarColumn = new TObjectName();
4256                                        newStarColumn.setString("*");
4257                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4258                                                        true);
4259
4260                                        Process process = modelFactory.createProcess(stmt);
4261                                        newNameTableModel.addProcess(process);
4262                                        {
4263                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4264                                                relation.setEffectType(EffectType.exchange_partition);
4265                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4266                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4267                                                if (option.getPartitionName() != null) {
4268                                                        relation.setPartition(option.getPartitionName().toString());
4269                                                }
4270                                                relation.setProcess(process);
4271                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4272                                                        oldTableStarColumn.setShowStar(false);
4273                                                        relation.setShowStarRelation(false);
4274                                                }
4275
4276                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4277                                                        newTableStarColumn.setShowStar(false);
4278                                                        relation.setShowStarRelation(false);
4279                                                }
4280                                        }
4281                                        {
4282                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4283                                                relation.setEffectType(EffectType.exchange_partition);
4284                                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4285                                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4286                                                if (option.getPartitionName() != null) {
4287                                                        relation.setPartition(option.getPartitionName().toString());
4288                                                }
4289                                                relation.setProcess(process);
4290                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4291                                                        oldTableStarColumn.setShowStar(false);
4292                                                        relation.setShowStarRelation(false);
4293                                                }
4294
4295                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4296                                                        newTableStarColumn.setShowStar(false);
4297                                                        relation.setShowStarRelation(false);
4298                                                }
4299                                        }
4300                                }
4301                        }
4302                        else if(option.getOptionType() == EAlterTableOptionType.setLocation) {
4303                                TObjectName location = option.getTableLocation();
4304                                Process process = modelFactory.createProcess(stmt);
4305                                process.setType("Set Table Location");
4306                                oldNameTableModel.addProcess(process);
4307                                Table uriFile = modelFactory.createTableByName(location, true);
4308                                uriFile.setPath(true);
4309                                for (int j = 0; j < oldNameTableModel.getColumns().size(); j++) {
4310                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4311                                        TObjectName fileUri = new TObjectName();
4312                                        fileUri.setString("*");
4313                                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
4314                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4315                                        relation.setTarget(new TableColumnRelationshipElement(oldNameTableModel.getColumns().get(j)));
4316                                        relation.setProcess(process);
4317                                }
4318                        }
4319                        else if (option.getOptionType() == EAlterTableOptionType.AddColumn
4320                                        || option.getOptionType() == EAlterTableOptionType.addColumnIfNotExists) {
4321                                if (option.getColumnDefinitionList() != null) {
4322                                        for (TColumnDefinition column : option.getColumnDefinitionList()) {
4323                                                if (column != null && column.getColumnName() != null) {
4324                                                        TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column.getColumnName(), true);
4325                                                        if(this.option.getAnalyzeMode() == AnalyzeMode.crud) {
4326                                                                CrudRelationship crudRelationship = modelFactory.createCrudRelation();
4327                                                                crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
4328                                                                crudRelationship.setEffectType(EffectType.add_table_column);
4329                                                        }
4330                                                }
4331                                        }
4332                                }
4333                        }
4334                        else if (option.getOptionType() == EAlterTableOptionType.DropColumn && this.option.getAnalyzeMode() == AnalyzeMode.crud) {
4335                                if (option.getColumnNameList() != null) {
4336                                        for (TObjectName column : option.getColumnNameList()) {
4337                                                TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column, true);
4338                                                CrudRelationship crudRelationship = modelFactory.createCrudRelation();
4339                                                crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
4340                                                crudRelationship.setEffectType(EffectType.drop_table_column);
4341                                        }
4342                                }
4343                        }
4344                        else if(option.getOptionType() == EAlterTableOptionType.AddConstraint || option.getOptionType() == EAlterTableOptionType.AddConstraintFK
4345                                        || option.getOptionType() == EAlterTableOptionType.AddConstraintPK || option.getOptionType() == EAlterTableOptionType.AddConstraintUnique
4346                                        || option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){
4347                                if (option.getTableConstraint() != null) {
4348                                        TConstraint alertTableConstraint = option.getTableConstraint();
4349                                        TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList();
4350                                        for (int k = 0; k < keyNames.size(); k++) {
4351                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
4352                                                TObjectName referencedTableName = alertTableConstraint.getReferencedObject();
4353                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4354                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
4355                                                if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){
4356                                                        tableConstraint.setPrimaryKey(true);
4357                                                }
4358                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){
4359                                                        tableConstraint.setIndexKey(true);
4360                                                }
4361                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){
4362                                                        tableConstraint.setUnqiueKey(true);
4363                                                }
4364                                                else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
4365                                                        tableConstraint.setForeignKey(true);
4366                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
4367                                                        if (referencedTable == null) {
4368                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
4369                                                        }
4370                                                        TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList();
4371                                                        if (referencedTableColumns != null) {
4372                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
4373                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
4374                                                                                        referencedTableColumns.getObjectName(j), false);
4375                                                                        if (tableColumn != null) {
4376                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4377                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
4378                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4379                                                                                relation.setEffectType(EffectType.foreign_key);
4380                                                                                Process process = modelFactory.createProcess(stmt);
4381                                                                                relation.setProcess(process);
4382                                                                                if(this.option.isShowERDiagram()){
4383                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
4384                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4385                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4386                                                                                }
4387                                                                        }
4388                                                                }
4389                                                        }
4390                                                        else{
4391                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
4392                                                                if (tableColumn != null) {
4393                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4394                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
4395                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4396                                                                        relation.setEffectType(EffectType.foreign_key);
4397                                                                        if(this.option.isShowERDiagram()){
4398                                                                                ERRelationship erRelation = modelFactory.createERRelation();
4399                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4400                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4401                                                                        }
4402                                                                }
4403                                                        }
4404                                                }
4405                                        }
4406                                }
4407                                else if (option.getConstraintList() != null) {
4408                                        for(int iCons=0; iCons<option.getConstraintList().size(); iCons++){
4409                                                TConstraint alertTableConstraint = option.getConstraintList().getConstraint(iCons);
4410                                                TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList();
4411                                                if(keyNames != null){
4412                                                        for (int k = 0; k < keyNames.size(); k++) {
4413                                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
4414                                                                TObjectName referencedTableName = alertTableConstraint.getReferencedObject();
4415                                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4416                                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
4417                                                                if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){
4418                                                                        tableConstraint.setPrimaryKey(true);
4419                                                                }
4420                                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){
4421                                                                        tableConstraint.setIndexKey(true);
4422                                                                }
4423                                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){
4424                                                                        tableConstraint.setUnqiueKey(true);
4425                                                                }
4426                                                                else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
4427                                                                        tableConstraint.setForeignKey(true);
4428                                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
4429                                                                        if (referencedTable == null) {
4430                                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
4431                                                                        }
4432                                                                        TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList();
4433                                                                        if (referencedTableColumns != null) {
4434                                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
4435                                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
4436                                                                                                        referencedTableColumns.getObjectName(j), false);
4437                                                                                        if (tableColumn != null) {
4438                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4439                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
4440                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4441                                                                                                relation.setEffectType(EffectType.foreign_key);
4442                                                                                                Process process = modelFactory.createProcess(stmt);
4443                                                                                                relation.setProcess(process);
4444                                                                                                if(this.option.isShowERDiagram()){
4445                                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
4446                                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4447                                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4448                                                                                                }
4449                                                                                        }
4450                                                                                }
4451                                                                        }
4452                                                                        else{
4453                                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
4454                                                                                if (tableColumn != null) {
4455                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4456                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
4457                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4458                                                                                        relation.setEffectType(EffectType.foreign_key);
4459                                                                                        Process process = modelFactory.createProcess(stmt);
4460                                                                                        relation.setProcess(process);
4461                                                                                        if(this.option.isShowERDiagram()){
4462                                                                                                ERRelationship erRelation = modelFactory.createERRelation();
4463                                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4464                                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4465                                                                                        }
4466                                                                                }
4467                                                                        }
4468                                                                }
4469                                                        }
4470                                                }
4471                                        }
4472                                }
4473                                else if (option.getIndexCols() != null){
4474                                        TPTNodeList<TColumnWithSortOrder> keyNames = option.getIndexCols();
4475                                        for (int k = 0; k < keyNames.size(); k++) {
4476                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
4477                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4478                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
4479                                                if(option.getOptionType() == EAlterTableOptionType.AddConstraintPK){
4480                                                        tableConstraint.setPrimaryKey(true);
4481                                                }
4482                                                else if(option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){
4483                                                        tableConstraint.setIndexKey(true);
4484                                                }
4485                                                else if(option.getOptionType() == EAlterTableOptionType.AddConstraintUnique){
4486                                                        tableConstraint.setUnqiueKey(true);
4487                                                }
4488                                                else if (option.getOptionType() == EAlterTableOptionType.AddConstraintFK) {
4489                                                        TObjectName referencedTableName = option.getReferencedObjectName();
4490                                                        tableConstraint.setForeignKey(true);
4491                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
4492                                                        if (referencedTable == null) {
4493                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
4494                                                        }
4495                                                        TObjectNameList referencedTableColumns = option.getReferencedColumnList();
4496                                                        if (referencedTableColumns != null) {
4497                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
4498                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
4499                                                                                        referencedTableColumns.getObjectName(j), false);
4500                                                                        if (tableColumn != null) {
4501                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4502                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
4503                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4504                                                                                relation.setEffectType(EffectType.foreign_key);
4505                                                                                Process process = modelFactory.createProcess(stmt);
4506                                                                                relation.setProcess(process);
4507                                                                                if(this.option.isShowERDiagram()){
4508                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
4509                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4510                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4511                                                                                }
4512                                                                        }
4513                                                                }
4514                                                        }
4515                                                        else{
4516                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
4517                                                                if (tableColumn != null) {
4518                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4519                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
4520                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4521                                                                        relation.setEffectType(EffectType.foreign_key);
4522                                                                        Process process = modelFactory.createProcess(stmt);
4523                                                                        relation.setProcess(process);
4524                                                                        if(this.option.isShowERDiagram()){
4525                                                                                ERRelationship erRelation = modelFactory.createERRelation();
4526                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4527                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4528                                                                        }
4529                                                                }
4530                                                        }
4531                                                }
4532                                        }
4533                                }
4534                        }
4535                }
4536        }
4537
4538        private void analyzeDeleteStmt(TDeleteSqlStatement stmt) {
4539                TTable table = stmt.getTargetTable();
4540                if (table == null)
4541                        return;
4542                
4543                if (table.getCTE() != null) {
4544                        table = table.getCTE().getSubquery().getTables().getTable(0);
4545                } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) {
4546                        table = table.getLinkTable().getSubquery().getTables().getTable(0);
4547                } else if (table.getSubquery() != null) {
4548                        table = table.getSubquery().getTables().getTable(0);
4549                }
4550                
4551                Table tableModel = modelFactory.createTable(table);
4552                if (table.getLinkedColumns() != null && table.getLinkedColumns().size() > 0) {
4553                        for (int j = 0; j < table.getLinkedColumns().size(); j++) {
4554                                TObjectName object = table.getLinkedColumns().getObjectName(j);
4555
4556                                if (object.getDbObjectType() == EDbObjectType.variable) {
4557                                        continue;
4558                                }
4559
4560                                if (object.getColumnNameOnly().startsWith("@")
4561                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
4562                                        continue;
4563                                }
4564
4565                                if (object.getColumnNameOnly().startsWith(":")
4566                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
4567                                        continue;
4568                                }
4569
4570                                if (!isBuiltInFunctionName(object)) {
4571                                        if (object.getSourceTable() == null || object.getSourceTable() == table) {
4572                                                modelFactory.createTableColumn(tableModel, object, false);
4573                                        }
4574                                }
4575                        }
4576                }
4577
4578                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
4579                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
4580                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
4581                        crudRelationship.setEffectType(EffectType.delete);
4582                }
4583                
4584                if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) {
4585                        analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where,
4586                                        EffectType.delete);
4587                }
4588        }
4589
4590        private TObjectName getProcedureName(TStoredProcedureSqlStatement stmt) {
4591                if (stmt instanceof TTeradataCreateProcedure) {
4592                        return ((TTeradataCreateProcedure) stmt).getProcedureName();
4593                }
4594                return stmt.getStoredProcedureName();
4595        }
4596
4597        private void analyzePlsqlCreatePackage(TPlsqlCreatePackage stmt) {
4598                TObjectName procedureName = getProcedureName(stmt);
4599                OraclePackage oraclePackage;
4600                if (procedureName != null) {
4601                        if (this.modelManager.getOraclePackageByName(
4602                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))) == null) {
4603                                oraclePackage = this.modelFactory.createOraclePackage(stmt);
4604
4605                                if (stmt.getParameterDeclarations() != null) {
4606                                        TParameterDeclarationList parameters = stmt.getParameterDeclarations();
4607
4608                                        for (int i = 0; i < parameters.size(); ++i) {
4609                                                TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i);
4610                                                if (parameter.getParameterName() != null) {
4611                                                        this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1);
4612                                                } else if (parameter.getDataType() != null) {
4613                                                        this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1);
4614                                                }
4615                                        }
4616                                }
4617
4618                                ModelBindingManager.setGlobalOraclePackage(oraclePackage);
4619                        } else {
4620                                ModelBindingManager.setGlobalOraclePackage(this.modelManager.getOraclePackageByName(
4621                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))));
4622                        }
4623                        
4624                        try {
4625                                if (stmt.getDeclareStatements() != null) {
4626                                        for (int i = 0; i < stmt.getDeclareStatements().size(); ++i) {
4627                                                analyzeCustomSqlStmt(stmt.getDeclareStatements().get(i));
4628                                        }
4629                                }
4630                        } finally {
4631                                ModelBindingManager.removeGlobalOraclePackage();
4632                        }
4633                }
4634        }
4635
4636        private void analyzeStoredProcedureStmt(TStoredProcedureSqlStatement stmt) {
4637
4638                if (stmt instanceof TPlsqlCreatePackage) {
4639                        analyzePlsqlCreatePackage((TPlsqlCreatePackage) stmt);
4640                        return;
4641                }
4642                
4643                ModelBindingManager.setGlobalProcedure(stmt);
4644
4645                try {
4646                        Procedure procedure = null;
4647        
4648                        TObjectName procedureName = getProcedureName(stmt);
4649                        if (procedureName != null) {
4650                                procedure = this.modelFactory.createProcedure(stmt);
4651                                if (procedure != null) {
4652                                        modelManager.bindModel(stmt, procedure);
4653                                }
4654                                if (ModelBindingManager.getGlobalOraclePackage() != null) {
4655                                        ModelBindingManager.getGlobalOraclePackage().addProcedure(procedure);
4656                                        procedure.setParentPackage(ModelBindingManager.getGlobalOraclePackage());
4657                                }
4658                                if (stmt.getParameterDeclarations() != null) {
4659                                        TParameterDeclarationList parameters = stmt.getParameterDeclarations();
4660        
4661                                        for (int i = 0; i < parameters.size(); ++i) {
4662                                                TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i);
4663                                                Argument argument = null;
4664                                                TObjectName argumentName = null;
4665                                                if (parameter.getParameterName() != null) {
4666                                                        argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1);
4667                                                        argumentName = parameter.getParameterName();
4668                                                } else if (parameter.getDataType() != null) {
4669                                                        argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1);
4670                                                }
4671                                                
4672                                                if (argument != null) {
4673                                                        if (argumentName == null) {
4674                                                                argumentName = new TObjectName();
4675                                                                argumentName.setString(argument.getName());
4676                                                        }
4677                                                        Variable variable = modelFactory.createVariable(argument.getName());
4678                                                        if (argument.getMode() == EParameterMode.in || argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
4679                                                                variable.setSubType(SubType.of(argument.getMode().name()));
4680                                                        } else {
4681                                                                variable.setSubType(SubType.argument);
4682                                                        }
4683                                                        if(isSimpleDataType(argument.getDataType())){
4684                                                                modelFactory.createTableColumn(variable, argumentName, true);
4685                                                        }
4686                                                        else {
4687                                                                TObjectName variableProperties = new TObjectName();
4688                                                                variableProperties.setString("*");
4689                                                                modelFactory.createTableColumn(variable, variableProperties, true);
4690                                                        }
4691                                                }
4692                                        }
4693                                }
4694                        }
4695        
4696                        if (stmt instanceof TCreateTriggerStmt) {
4697                                TCreateTriggerStmt trigger = (TCreateTriggerStmt) stmt;
4698        
4699                                if (trigger.getFunctionCall() != null) {
4700                                        modelFactory.createProcedureFromFunctionCall(trigger.getFunctionCall());
4701                                }
4702        
4703                                if (trigger.getTables() != null) {
4704                                        for (int i = 0; i < trigger.getTables().size(); i++) {
4705                                                Table tableModel = this.modelFactory.createTriggerOnTable(trigger.getTables().getTable(i));
4706                                        }
4707                                }
4708                        }
4709        
4710                        if (stmt instanceof TPlsqlCreateTrigger
4711                                        && ((TPlsqlCreateTrigger) stmt).getTriggeringClause().getEventClause() instanceof TDmlEventClause) {
4712                                TPlsqlCreateTrigger trigger = (TPlsqlCreateTrigger) stmt;
4713                                TDmlEventClause clause = (TDmlEventClause) ((TPlsqlCreateTrigger) stmt).getTriggeringClause()
4714                                                .getEventClause();
4715                                Table sourceTable = modelFactory.createTableByName(clause.getTableName());
4716        
4717                                for (TTriggerEventItem item : clause.getEventItems()) {
4718                                        if (item instanceof TDmlEventItem) {
4719                                                if (((TDmlEventItem) item).getColumnList() != null) {
4720                                                        for (TObjectName column : ((TDmlEventItem) item).getColumnList()) {
4721                                                                modelFactory.createTableColumn(sourceTable, column, true);
4722                                                        }
4723                                                }
4724                                        }
4725                                }
4726        
4727                                for (TCustomSqlStatement subStmt : ((TPlsqlCreateTrigger) stmt).getStatements()) {
4728                                        if (!(subStmt instanceof TCommonBlock))
4729                                                continue;
4730                                        for (TCustomSqlStatement blockSubStmt : ((TCommonBlock) subStmt).getStatements()) {
4731                                                if (!(blockSubStmt instanceof TBasicStmt))
4732                                                        continue;
4733                                                TBasicStmt basicStmt = (TBasicStmt) blockSubStmt;
4734                                                TExpression expression = basicStmt.getExpr();
4735                                                if (expression != null && expression.getExpressionType() == EExpressionType.function_t) {
4736                                                        Procedure targetProcedure = modelManager.getProcedureByName(DlineageUtil
4737                                                                        .getTableFullName(expression.getFunctionCall().getFunctionName().toString()));
4738                                                        if (targetProcedure == null) {
4739                                                                targetProcedure = modelManager
4740                                                                                .getProcedureByName(DlineageUtil.getTableFullName(procedure.getSchema() + "."
4741                                                                                                + expression.getFunctionCall().getFunctionName().toString()));
4742                                                        }
4743                                                        if (targetProcedure != null && expression.getFunctionCall().getArgs() != null && expression
4744                                                                        .getFunctionCall().getArgs().size() == targetProcedure.getArguments().size()) {
4745                                                                for (int j = 0; j < expression.getFunctionCall().getArgs().size(); j++) {
4746                                                                        TExpression columnExpr = expression.getFunctionCall().getArgs().getExpression(j);
4747                                                                        if (columnExpr.getExpressionType() == EExpressionType.simple_object_name_t) {
4748                                                                                TObjectName columnObject = columnExpr.getObjectOperand();
4749                                                                                if (columnObject.toString().indexOf(":") != -1) {
4750                                                                                        TableColumn tableColumn = modelFactory.createTableColumn(sourceTable,
4751                                                                                                        columnObject, true);
4752                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4753                                                                                        relation.setEffectType(EffectType.trigger);
4754                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
4755                                                                                        relation.setTarget(
4756                                                                                                        new ArgumentRelationshipElement(targetProcedure.getArguments().get(j)));
4757                                                                                        Process process = modelFactory.createProcess(stmt);
4758                                                                                        relation.setProcess(process);
4759                                                                                }
4760                                                                        }
4761                                                                }
4762                                                        }
4763                                                }
4764                                        }
4765                                }
4766                        }
4767        
4768                        if (stmt instanceof TMssqlCreateFunction) {
4769                                TMssqlCreateFunction createFunction = (TMssqlCreateFunction) stmt;
4770                                if (createFunction.getReturnTableVaraible() != null && createFunction.getReturnTableDefinitions() != null) {
4771                                        Table tableModel = this.modelFactory.createTableByName(createFunction.getReturnTableVaraible(), true);
4772                                        tableModel.setCreateTable(true);
4773                                        String procedureParent = createFunction.getFunctionName().toString();
4774                                        if (procedureParent != null) {
4775                                                tableModel.setParent(procedureParent);
4776                                        }
4777                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
4778        
4779                                        if (createFunction.getReturnTableDefinitions() != null) {
4780                                                for (int j = 0; j < createFunction.getReturnTableDefinitions().size(); j++) {
4781                                                        TTableElement tableElement = createFunction.getReturnTableDefinitions().getTableElement(j);
4782                                                        TColumnDefinition column = tableElement.getColumnDefinition();
4783                                                        if (column != null && column.getColumnName() != null) {
4784                                                                modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
4785                                                        }
4786                                                }
4787                                        }
4788                                }
4789        
4790                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) {
4791                                        String procedureParent = createFunction.getFunctionName().toString();
4792                                        analyzeSelectStmt(createFunction.getReturnStmt().getSubquery());
4793                                        ResultSet resultSetModel = (ResultSet) modelManager
4794                                                        .getModel(createFunction.getReturnStmt().getSubquery());
4795                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
4796                                                        resultSetModel);
4797                                }
4798                        } else if (stmt instanceof TCreateFunctionStmt) {
4799                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt;
4800                                if (createFunction.getReturnDataType() != null
4801                                                && createFunction.getReturnDataType().getColumnDefList() != null) {
4802                                        Table tableModel = this.modelFactory.createTableByName(createFunction.getFunctionName(), true);
4803                                        tableModel.setCreateTable(true);
4804                                        String procedureParent = createFunction.getFunctionName().toString();
4805                                        if (procedureParent != null) {
4806                                                tableModel.setParent(procedureParent);
4807                                        }
4808        
4809                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
4810                                        for (int j = 0; j < createFunction.getReturnDataType().getColumnDefList().size(); j++) {
4811                                                TColumnDefinition column = createFunction.getReturnDataType().getColumnDefList().getColumn(j);
4812                                                if (column != null && column.getColumnName() != null) {
4813                                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
4814                                                }
4815                                        }
4816        
4817                                        if (createFunction.getSqlQuery() != null) {
4818                                                analyzeSelectStmt(createFunction.getSqlQuery());
4819                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(createFunction.getSqlQuery());
4820                                                if (resultSetModel != null) {
4821                                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
4822                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
4823                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
4824                                                                        TableColumn tableColumn = tableModel.getColumns().get(j);
4825                                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(resultColumn.getName()),
4826                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
4827                                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4828                                                                                dataflowRelation.setEffectType(EffectType.select);
4829                                                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
4830                                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
4831                                                                        }
4832                                                                }
4833                                                        }
4834                                                }
4835                                        }
4836                                }
4837                                
4838                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) {
4839                                        String procedureParent = createFunction.getFunctionName().toString();
4840                                        analyzeSelectStmt(createFunction.getReturnStmt().getSubquery());
4841                                        ResultSet resultSetModel = (ResultSet) modelManager
4842                                                        .getModel(createFunction.getReturnStmt().getSubquery());
4843                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
4844                                                        resultSetModel);
4845                                }
4846                                
4847                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getReturnExpr() != null) {
4848                                        TExpression returnExpression =  createFunction.getReturnStmt().getReturnExpr();
4849                                        ResultSet returnResult = modelFactory.createResultSet(createFunction.getReturnStmt(), false);
4850                                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
4851                                        
4852                                        TExpression expression = createFunction.getReturnStmt().getReturnExpr();
4853                                        analyzeResultColumnExpressionRelation(resultColumn, expression);
4854        
4855                                        String procedureParent = createFunction.getFunctionName().toString();
4856                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
4857                                                        returnResult);
4858                                }
4859                        }
4860        
4861                        if (stmt instanceof TCreateProcedureStmt) {
4862                                TCreateProcedureStmt createProcedure = (TCreateProcedureStmt) stmt;
4863                                if (EDbVendor.dbvsnowflake == option.getVendor() && createProcedure.getRoutineBodyInConstant() != null) {
4864                                        extractSnowflakeSQLFromProcedure(createProcedure);
4865                                }
4866                        }
4867                                
4868                        if (stmt.getStatements().size() > 0) {
4869                                for (int i = 0; i < stmt.getStatements().size(); ++i) {
4870                                        this.analyzeCustomSqlStmt(stmt.getStatements().get(i));
4871                                }
4872                        }
4873
4874                        if (stmt.getBodyStatements().size() > 0) {
4875                                for (int i = 0; i < stmt.getBodyStatements().size(); ++i) {
4876                                        this.analyzeCustomSqlStmt(stmt.getBodyStatements().get(i));
4877                                }
4878                        }
4879                        
4880                        if (procedure != null && !procedure.getArguments().isEmpty() && stmt.getBodyStatements().size() == 1
4881                                        && stmt.getBodyStatements().get(0) instanceof TSelectSqlStatement) {
4882                                ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getBodyStatements().get(0));
4883                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedure.getName()),
4884                                                resultSet);
4885//                              List<Argument> outArgs = new ArrayList<Argument>();
4886//                              for (int i = 0; i < procedure.getArguments().size(); i++) {
4887//                                      Argument argument = procedure.getArguments().get(i);
4888//                                      if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
4889//                                              outArgs.add(argument);
4890//                                      }
4891//                              }
4892//
4893//                              if (resultSet != null && resultSet.getColumns().size() == outArgs.size()) {
4894//                                      for (int i = 0; i < outArgs.size(); i++) {
4895//                                              Argument argument = outArgs.get(i);
4896//                                              Variable variable = modelFactory.createVariable(argument.getName(), false);
4897//                                              if (variable != null) {
4898//                                                      DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4899//                                                      dataflowRelation.setEffectType(EffectType.output);
4900//                                                      dataflowRelation
4901//                                                                      .addSource(new ResultColumnRelationshipElement(resultSet.getColumns().get(i)));
4902//                                                      dataflowRelation
4903//                                                                      .setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0)));
4904//                                              }
4905//                                      }
4906//
4907//                              }
4908                        }
4909
4910                        if (stmt instanceof TCreateFunctionStmt && ((TCreateFunctionStmt)stmt).getSqlExpression()!=null) {
4911                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt;
4912                                TExpression returnExpression = createFunction.getSqlExpression();
4913
4914                                ResultSet returnResult = modelFactory.createResultSet(stmt, false);
4915                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
4916
4917                                columnsInExpr visitor = new columnsInExpr();
4918                                returnExpression.inOrderTraverse(visitor);
4919
4920                                List<TObjectName> objectNames = visitor.getObjectNames();
4921                                List<TParseTreeNode> functions = visitor.getFunctions();
4922                                List<TParseTreeNode> constants = visitor.getConstants();
4923                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
4924
4925                                if (functions != null && !functions.isEmpty()) {
4926                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
4927                                }
4928                                if (subquerys != null && !subquerys.isEmpty()) {
4929                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
4930                                }
4931                                if (objectNames != null && !objectNames.isEmpty()) {
4932                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
4933                                }
4934                                if (constants != null && !constants.isEmpty()) {
4935                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
4936                                }
4937
4938                                String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
4939                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
4940                                                returnResult);
4941                        }
4942                } finally {
4943                        ModelBindingManager.removeGlobalProcedure();
4944                }
4945
4946        }
4947
4948        private boolean isSimpleDataType(TTypeName dataType) {
4949                if (dataType.getDataType() == EDataType.variant_t) {
4950                        return false;
4951                }
4952                if (dataType.getDataType() == EDataType.cursor_t) {
4953                        return false;
4954                }
4955                if (dataType.getDataType() == EDataType.generic_t) {
4956                        return false;
4957                }
4958                if (dataType.getDataType() == EDataType.unknown_t) {
4959                        return false;
4960                }
4961                if (dataType.getDataType() == EDataType.sql_variant_t) {
4962                        return false;
4963                }
4964                if (dataType.getDataType() == EDataType.table_t) {
4965                        return false;
4966                }
4967                if (dataType.getDataType() == EDataType.raw_t) {
4968                        return false;
4969                }
4970                if (dataType.getDataType() == EDataType.resultset_t) {
4971                        return false;
4972                }
4973                if (dataType.getDataType() == EDataType.row_t) {
4974                        return false;
4975                }
4976                if (dataType.getDataType() == EDataType.map_t) {
4977                        return false;
4978                }
4979                if (dataType.getDataType() == EDataType.anyType_t) {
4980                        return false;
4981                }
4982                if (dataType.getDataType() == EDataType.struct_t) {
4983                        return false;
4984                }
4985                if (dataType.getDataType() == EDataType.structType_t) {
4986                        return false;
4987                }
4988                if (dataType.getDataType() == EDataType.mapType_t) {
4989                        return false;
4990                }
4991                return true;
4992        }
4993
4994        protected void analyzeResultColumnExpressionRelation(Object resultColumn, TExpression expression) {
4995                columnsInExpr visitor = new columnsInExpr();
4996                expression.inOrderTraverse(visitor);
4997                List<TObjectName> objectNames = visitor.getObjectNames();
4998                List<TParseTreeNode> functions = visitor.getFunctions();
4999                List<TParseTreeNode> constants = visitor.getConstants();
5000                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5001
5002                if (functions != null && !functions.isEmpty()) {
5003                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5004                }
5005                if (subquerys != null && !subquerys.isEmpty()) {
5006                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5007                }
5008                if (objectNames != null && !objectNames.isEmpty()) {
5009                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5010                }
5011                if (constants != null && !constants.isEmpty()) {
5012                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5013                }
5014        }
5015
5016        private void analyzeDb2ReturnStmt(TDb2ReturnStmt stmt) {
5017                if (stmt.getReturnExpr() != null) {
5018                        TExpression returnExpression = stmt.getReturnExpr();
5019                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5020                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5021                        
5022                        columnsInExpr visitor = new columnsInExpr();
5023                        stmt.getReturnExpr().inOrderTraverse(visitor);
5024                        
5025                        List<TObjectName> objectNames = visitor.getObjectNames();
5026                        List<TParseTreeNode> functions = visitor.getFunctions();
5027                        List<TParseTreeNode> constants = visitor.getConstants();
5028                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5029
5030                        if (functions != null && !functions.isEmpty()) {
5031                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5032                        }
5033                        if (subquerys != null && !subquerys.isEmpty()) {
5034                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5035                        }
5036                        if (objectNames != null && !objectNames.isEmpty()) {
5037                                analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5038                        }
5039                        if (constants != null && !constants.isEmpty()) {
5040                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5041                        }
5042
5043                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5044                        if (procedureParent != null) {
5045                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5046                                                returnResult);
5047                        }
5048                }
5049        }
5050
5051        private void analyzeReturnStmt(TReturnStmt stmt) {
5052                if (stmt.getResultColumnList() != null) {
5053                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5054                        for (TResultColumn column : stmt.getResultColumnList()) {
5055                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column);
5056
5057                                columnsInExpr visitor = new columnsInExpr();
5058                                column.getExpr().inOrderTraverse(visitor);
5059
5060                                List<TObjectName> objectNames = visitor.getObjectNames();
5061                                List<TParseTreeNode> functions = visitor.getFunctions();
5062                                List<TParseTreeNode> constants = visitor.getConstants();
5063                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5064
5065                                if (functions != null && !functions.isEmpty()) {
5066                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5067                                }
5068                                if (subquerys != null && !subquerys.isEmpty()) {
5069                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5070                                }
5071                                if (objectNames != null && !objectNames.isEmpty()) {
5072                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5073                                }
5074                                if (constants != null && !constants.isEmpty()) {
5075                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5076                                }
5077
5078                        }
5079
5080                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5081                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5082                                        returnResult);
5083                }
5084                else if(stmt.getExpression()!=null){
5085                        TExpression returnExpression = stmt.getExpression();
5086                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5087                        
5088                        columnsInExpr visitor = null;
5089                        List<TSelectSqlStatement> subquerys = null;
5090                        
5091                        if (returnExpression.getFunctionCall() != null
5092                                        && returnExpression.getFunctionCall().getFunctionName().toString().equalsIgnoreCase("table")
5093                                        && returnExpression.getFunctionCall().getArgs() != null
5094                                        && returnExpression.getFunctionCall().getArgs().size()>0) {
5095                                visitor = new columnsInExpr();
5096                                returnExpression.getFunctionCall().getArgs().getExpression(0).inOrderTraverse(visitor);
5097                                subquerys = visitor.getSubquerys();
5098                                if (subquerys != null && !subquerys.isEmpty()) {
5099                                        analyzeSelectStmt(subquerys.get(0));
5100                                        ResultSet resultSet = (ResultSet) modelManager.getModel(subquerys.get(0));
5101                                        if (resultSet != null && resultSet.getColumns() != null) {
5102                                                for (ResultColumn column : resultSet.getColumns()) {
5103                                                        TObjectName columnName = new TObjectName();
5104                                                        columnName.setString(column.getName());
5105                                                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, columnName);
5106                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5107                                                        dataflowRelation.setEffectType(EffectType.select);
5108                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(column));
5109                                                        dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5110                                                }
5111                                        }
5112                                        returnResult.setDetermined(resultSet.isDetermined());
5113                                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5114                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5115                                                        returnResult);
5116                                        return;
5117                                }
5118                        }
5119                        
5120                        ResultColumn resultColumn = null;
5121                        if (returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5122                                TObjectName columnName = new TObjectName();
5123                                columnName.setString("*");
5124                                resultColumn = modelFactory.createResultColumn(returnResult, columnName);
5125                        }
5126                        else {
5127                                resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5128                        }
5129
5130                        visitor = new columnsInExpr();
5131                        stmt.getExpression().inOrderTraverse(visitor);
5132
5133                        List<TObjectName> objectNames = visitor.getObjectNames();
5134                        List<TParseTreeNode> functions = visitor.getFunctions();
5135                        List<TParseTreeNode> constants = visitor.getConstants();
5136                        subquerys = visitor.getSubquerys();
5137
5138                        if (functions != null && !functions.isEmpty()) {
5139                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5140                        }
5141                        if (subquerys != null && !subquerys.isEmpty()) {
5142                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5143                        }
5144                        if (objectNames != null && !objectNames.isEmpty()) {
5145                                analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5146                        }
5147                        if (constants != null && !constants.isEmpty()) {
5148                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5149                        }
5150
5151                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5152                        if (procedureParent != null) {
5153                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5154                                                returnResult);
5155                        }
5156                }
5157        }
5158
5159        private void analyzeMssqlReturnStmt(TMssqlReturn stmt) {
5160                if (stmt.getResultColumnList() != null) {
5161                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5162                        for (TResultColumn column : stmt.getResultColumnList()) {
5163                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column);
5164
5165                                columnsInExpr visitor = new columnsInExpr();
5166                                column.getExpr().inOrderTraverse(visitor);
5167
5168                                List<TObjectName> objectNames = visitor.getObjectNames();
5169                                List<TParseTreeNode> functions = visitor.getFunctions();
5170                                List<TParseTreeNode> constants = visitor.getConstants();
5171                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5172
5173                                if (functions != null && !functions.isEmpty()) {
5174                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5175                                }
5176                                if (subquerys != null && !subquerys.isEmpty()) {
5177                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5178                                }
5179                                if (objectNames != null && !objectNames.isEmpty()) {
5180                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5181                                }
5182                                if (constants != null && !constants.isEmpty()) {
5183                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5184                                }
5185
5186                        }
5187
5188                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5189                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5190                                        returnResult);
5191                }
5192                else if(stmt.getReturnExpr()!=null){
5193                        TExpression returnExpression = stmt.getReturnExpr();
5194                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5195                        
5196                        if (returnExpression.getSubQuery() == null) {
5197                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5198                                columnsInExpr visitor = new columnsInExpr();
5199                                stmt.getReturnExpr().inOrderTraverse(visitor);
5200
5201                                List<TObjectName> objectNames = visitor.getObjectNames();
5202                                List<TParseTreeNode> functions = visitor.getFunctions();
5203                                List<TParseTreeNode> constants = visitor.getConstants();
5204                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5205
5206                                if (functions != null && !functions.isEmpty()) {
5207                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5208                                }
5209                                if (subquerys != null && !subquerys.isEmpty()) {
5210                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5211                                }
5212                                if (objectNames != null && !objectNames.isEmpty()) {
5213                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5214                                }
5215                                if (constants != null && !constants.isEmpty()) {
5216                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5217                                }
5218                        }
5219                        else {
5220                                analyzeSelectStmt(returnExpression.getSubQuery());
5221                                ResultSet subResultSet = (ResultSet)modelManager.getModel(returnExpression.getSubQuery());
5222                                if (subResultSet != null) {
5223                                        for (ResultColumn subResultColumn : subResultSet.getColumns()) {
5224                                                TObjectName objectName = new TObjectName();
5225                                                objectName.setString(subResultColumn.getName());
5226                                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, objectName);
5227                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5228                                                dataflowRelation.setEffectType(EffectType.select);
5229                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(subResultColumn));
5230                                                dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5231
5232                                        }
5233                                        
5234                                        if(subResultSet.getRelationRows().hasRelation()) {
5235                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
5236                                                impactRelation.setEffectType(EffectType.select);
5237                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
5238                                                                subResultSet.getRelationRows()));
5239                                                impactRelation.setTarget(
5240                                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(returnResult.getRelationRows()));
5241                                        }
5242                                }
5243                        }
5244                        
5245                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5246                        if (procedureParent != null) {
5247                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5248                                                returnResult);
5249                        }
5250                }
5251        }
5252        
5253        private void analyzeFetchStmt(TFetchStmt stmt) {
5254                if (stmt.getVariableNames() != null) {
5255                        for (int i = 0; i < stmt.getVariableNames().size(); i++) {
5256                                TExpression variableExpression = stmt.getVariableNames().getExpression(i);
5257                                if (variableExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5258                                        TObjectName columnObject = variableExpression.getObjectOperand();
5259                                        if (columnObject.getDbObjectType() == EDbObjectType.variable) {
5260                                                continue;
5261                                        }
5262
5263                                        if (columnObject.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql
5264                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
5265                                                continue;
5266                                        }
5267
5268                                        if (columnObject.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana
5269                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
5270                                                continue;
5271                                        }
5272
5273                                        Variable cursorVariable = modelFactory.createVariable(columnObject);
5274                                        cursorVariable.setSubType(SubType.record);
5275                                        if (cursorVariable.isDetermined()) {
5276                                                if (stmt.getCursorName() != null) {
5277                                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5278                                                        String variableString = stmt.getCursorName().toString();
5279                                                        if (variableString.startsWith(":")) {
5280                                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5281                                                        }
5282                                                        if (!SQLUtil.isEmpty(procedureName)) {
5283                                                                variableString = procedureName + "."
5284                                                                                + SQLUtil.getIdentifierNormalTableName(variableString);
5285                                                        }
5286                                                        Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
5287                                                        if (cursor != null) {
5288                                                                for (TableColumn variableProperty : cursorVariable.getColumns()) {
5289                                                                        for (int j = 0; j < cursor.getColumns().size(); j++) {
5290                                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5291                                                                                dataflowRelation.setEffectType(EffectType.cursor);
5292                                                                                if (stmt.getVariableNames().size() == 1) {
5293                                                                                        dataflowRelation.addSource(
5294                                                                                                        new TableColumnRelationshipElement(cursor.getColumns().get(j)));
5295                                                                                } else {
5296                                                                                        dataflowRelation.addSource(
5297                                                                                                        new TableColumnRelationshipElement(cursor.getColumns().get(j), i));
5298                                                                                }
5299                                                                                dataflowRelation
5300                                                                                                .setTarget(new TableColumnRelationshipElement(variableProperty));
5301                                                                        }
5302                                                                }
5303                                                        }
5304                                                }
5305                                                
5306                                        } else {
5307                                                TableColumn variableProperty = null;
5308                                                if (stmt.getVariableNames().size() == 1) {
5309                                                        if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
5310                                                                TObjectName starColumn = new TObjectName();
5311                                                                starColumn.setString("*");
5312                                                                variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
5313                                                        } else {
5314                                                                variableProperty = cursorVariable.getColumns().get(0);
5315                                                        }
5316                                                } else {
5317                                                        variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true);
5318                                                }
5319
5320                                                if (stmt.getCursorName() != null) {
5321                                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5322                                                        String variableString = stmt.getCursorName().toString();
5323                                                        if (variableString.startsWith(":")) {
5324                                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5325                                                        }
5326                                                        if (!SQLUtil.isEmpty(procedureName)) {
5327                                                                variableString = procedureName + "."
5328                                                                                + SQLUtil.getIdentifierNormalTableName(variableString);
5329                                                        }
5330                                                        Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
5331                                                        if (cursor != null) {
5332                                                                for (int j = 0; j < cursor.getColumns().size(); j++) {
5333                                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5334                                                                        dataflowRelation.setEffectType(EffectType.cursor);
5335                                                                        if (stmt.getVariableNames().size() == 1) {
5336                                                                                dataflowRelation.addSource(
5337                                                                                                new TableColumnRelationshipElement(cursor.getColumns().get(j)));
5338                                                                        } else {
5339                                                                                dataflowRelation.addSource(
5340                                                                                                new TableColumnRelationshipElement(cursor.getColumns().get(j), i));
5341                                                                        }
5342                                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5343                                                                }
5344                                                        }
5345                                                }
5346                                        }
5347                                }
5348                        }
5349                }
5350        }
5351
5352        private void analyzeFetchStmt(TMssqlFetch stmt) {
5353                if (stmt.getVariableNames() != null) {
5354                        for (int i = 0; i < stmt.getVariableNames().size(); i++) {
5355                                TObjectName columnObject = stmt.getVariableNames().getObjectName(i);
5356                                Variable cursorVariable = modelFactory.createVariable(columnObject);
5357                                cursorVariable.setCreateTable(true);
5358                                cursorVariable.setSubType(SubType.record);
5359                                TableColumn variableProperty = null;
5360                                if (stmt.getVariableNames().size() == 1) {
5361                                        if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
5362                                                TObjectName starColumn = new TObjectName();
5363                                                starColumn.setString("*");
5364                                                variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
5365                                        } else {
5366                                                variableProperty = cursorVariable.getColumns().get(0);
5367                                        }
5368                                } else {
5369                                        variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true);
5370                                }
5371
5372                                if (stmt.getCursorName() != null) {
5373                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5374                                        String variableString = stmt.getCursorName().toString();
5375                                        if (variableString.startsWith(":")) {
5376                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5377                                        }
5378                                        if (!SQLUtil.isEmpty(procedureName)) {
5379                                                variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
5380                                        }
5381                                        Table cursor = modelManager
5382                                                        .getTableByName(DlineageUtil.getTableFullName(variableString));
5383                                        if (cursor != null) {
5384                                                for (int j = 0; j < cursor.getColumns().size(); j++) {
5385                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5386                                                        dataflowRelation.setEffectType(EffectType.cursor);
5387                                                        if (stmt.getVariableNames().size() == 1) {
5388                                                                dataflowRelation
5389                                                                                .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j)));
5390                                                        } else {
5391                                                                dataflowRelation
5392                                                                                .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j), i));
5393                                                        }
5394                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5395                                                }
5396                                        }
5397                                }
5398                        }
5399
5400                }
5401        }
5402
5403        private void analyzeLoopStmt(TLoopStmt stmt) {
5404
5405                if (stmt.getCursorName() != null && stmt.getIndexName() != null) {
5406                        modelManager.bindCursorIndex(stmt.getIndexName(), stmt.getCursorName());
5407                }
5408
5409                if (stmt.getRecordName() != null && stmt.getSubquery() != null) {
5410                        Variable cursorTempTable = modelFactory.createCursor(stmt);
5411                        cursorTempTable.setVariable(true);
5412                        cursorTempTable.setSubType(SubType.cursor);
5413                        modelManager.bindCursorModel(stmt, cursorTempTable);
5414                        analyzeSelectStmt(stmt.getSubquery());
5415
5416                        TableColumn cursorColumn = null;
5417                        if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
5418                                TObjectName starColumn = new TObjectName();
5419                                starColumn.setString("*");
5420                                cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
5421                        } else {
5422                                cursorColumn = cursorTempTable.getColumns().get(0);
5423                        }
5424
5425
5426                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
5427                        if (resultSetModel != null) {
5428                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
5429                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
5430                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5431                                        dataflowRelation.setEffectType(EffectType.cursor);
5432                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
5433                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
5434                                }
5435                        }
5436                }
5437
5438                for (int i = 0; i < stmt.getStatements().size(); i++) {
5439                        analyzeCustomSqlStmt(stmt.getStatements().get(i));
5440                }
5441        }
5442
5443        private void analyzeForStmt(TForStmt stmt) {
5444                if (stmt.getSubquery() == null) {
5445                        return;
5446                }
5447
5448                Variable cursorTempTable = modelFactory.createCursor(stmt);
5449                cursorTempTable.setVariable(true);
5450                cursorTempTable.setSubType(SubType.cursor);
5451                cursorTempTable.setCreateTable(true);
5452                modelManager.bindCursorModel(stmt, cursorTempTable);
5453                analyzeSelectStmt(stmt.getSubquery());
5454
5455                TableColumn cursorColumn = null;
5456                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
5457                        TObjectName starColumn = new TObjectName();
5458                        starColumn.setString("*");
5459                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
5460                } else {
5461                        cursorColumn = cursorTempTable.getColumns().get(0);
5462                }
5463
5464
5465                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
5466                if (resultSetModel != null) {
5467                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
5468                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
5469                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5470                                dataflowRelation.setEffectType(EffectType.cursor);
5471                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
5472                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
5473                        }
5474                }
5475
5476                if (stmt.getStatements() != null && stmt.getStatements().size() > 0) {
5477                        for (int i = 0; i < stmt.getStatements().size(); i++) {
5478                                analyzeCustomSqlStmt(stmt.getStatements().get(i));
5479                        }
5480                }
5481        }
5482
5483        private void analyzeVarDeclStmt(TVarDeclStmt stmt) {
5484                TTypeName typeName = stmt.getDataType();
5485                if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) {
5486                        Variable cursorVariable = modelFactory.createVariable(stmt.getElementName());
5487                        cursorVariable.setSubType(SubType.record_type);
5488
5489                        Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false);
5490                        if(!variableTable.isCreateTable()) {
5491                                TObjectName starColumn1 = new TObjectName();
5492                                starColumn1.setString("*");
5493                                TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true);
5494                                variableTableStarColumn.setShowStar(false);
5495                                variableTableStarColumn.setExpandStar(true);
5496
5497                                TObjectName starColumn = new TObjectName();
5498                                starColumn.setString("*");
5499                                TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
5500                                variableProperty.setShowStar(false);
5501                                variableProperty.setExpandStar(true);
5502
5503                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5504                                dataflowRelation.setEffectType(EffectType.rowtype);
5505                                dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn));
5506                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5507                        } else {
5508                                for (TableColumn sourceColumn : variableTable.getColumns()) {
5509                                        String columnName = sourceColumn.getName();
5510                                        TObjectName targetColumn = new TObjectName();
5511                                        targetColumn.setString(columnName);
5512                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true);
5513                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5514                                        dataflowRelation.setEffectType(EffectType.rowtype);
5515                                        dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn));
5516                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5517                                }
5518                        }
5519                } else if (stmt.getElementName() != null) {
5520                        Variable variable = modelFactory.createVariable(stmt.getElementName());
5521                        variable.setCreateTable(true);
5522                        variable.setSubType(SubType.record);
5523                        TableColumn tableColumn = null;
5524                        if (stmt.getDataType() != null && (modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false)!=null || isCursorType(stmt.getDataType().getDataTypeName()))) {
5525                                Variable cursorVariable = modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false);
5526                                if (cursorVariable != null) {
5527                                        if (cursorVariable.getSubType() == SubType.record_type) {
5528                                                variable.setSubType(SubType.record_type);
5529                                        }
5530                                        if(cursorVariable.isDetermined()) {
5531                                                for (int k = 0; k < cursorVariable.getColumns().size(); k++) {
5532                                                        TableColumn sourceColumn = cursorVariable.getColumns().get(k);
5533                                                        TObjectName objectName = new TObjectName();
5534                                                        objectName.setString(sourceColumn.getName());
5535                                                        tableColumn = modelFactory.createTableColumn(variable, objectName, true);
5536                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5537                                                        dataflowRelation.setEffectType(EffectType.cursor);
5538                                                        dataflowRelation
5539                                                                        .addSource(new TableColumnRelationshipElement(sourceColumn));
5540                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
5541                                                }
5542                                                variable.setDetermined(true);
5543                                                return;
5544                                        }
5545                                        else {
5546                                                TObjectName objectName = new TObjectName();
5547                                                objectName.setString("*");
5548                                                tableColumn = modelFactory.createTableColumn(variable, objectName, true);
5549                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5550                                                dataflowRelation.setEffectType(EffectType.cursor);
5551                                                dataflowRelation
5552                                                                .addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
5553                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
5554                                        }
5555                                }
5556                                else {
5557                                        TObjectName objectName = new TObjectName();
5558                                        objectName.setString("*");
5559                                        tableColumn = modelFactory.createTableColumn(variable, objectName, true);                                       
5560                                }
5561                        } else {
5562                                tableColumn = modelFactory.createTableColumn(variable, stmt.getElementName(), true);
5563                                tableColumn.setVariant(true);
5564                        }
5565
5566                        if (stmt.getDefaultValue() != null) {
5567                                columnsInExpr visitor = new columnsInExpr();
5568                                stmt.getDefaultValue().inOrderTraverse(visitor);
5569                                List<TObjectName> objectNames = visitor.getObjectNames();
5570                                List<TParseTreeNode> functions = visitor.getFunctions();
5571                                List<TParseTreeNode> constants = visitor.getConstants();
5572                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5573
5574                                if (functions != null && !functions.isEmpty()) {
5575                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
5576                                }
5577                                if (subquerys != null && !subquerys.isEmpty()) {
5578                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
5579                                }
5580                                if (objectNames != null && !objectNames.isEmpty()) {
5581                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
5582                                }
5583                                if (constants != null && !constants.isEmpty()) {
5584                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
5585                                }
5586                        }
5587                        
5588                        
5589                }
5590        }
5591
5592        private boolean isCursorType(String dataTypeName) {
5593                if (dataTypeName != null && dataTypeName.toLowerCase().contains("cursor")) {
5594                        return true;
5595                }
5596                return false;
5597        }
5598
5599        private void analyzeSetStmt(TSetStmt stmt) {
5600                TExpression right = stmt.getVariableValue();
5601                TObjectName columnObject = stmt.getVariableName();
5602                if (columnObject != null) {
5603                        TableColumn tableColumn = null;
5604                        Variable tableModel;
5605                        if (columnObject.toString().indexOf(".") != -1) {
5606                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
5607                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
5608                        } else {
5609                                tableModel = modelFactory.createVariable(columnObject);
5610                        }
5611                        tableModel.setCreateTable(true);
5612                        tableModel.setSubType(SubType.record);
5613
5614                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
5615                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
5616                        } else {
5617                                tableColumn = tableModel.getColumns().get(0);
5618                        }
5619
5620                        if (tableColumn != null && right!=null) {
5621                                columnsInExpr visitor = new columnsInExpr();
5622                                right.inOrderTraverse(visitor);
5623                                List<TObjectName> objectNames = visitor.getObjectNames();
5624                                List<TParseTreeNode> functions = visitor.getFunctions();
5625                                List<TParseTreeNode> constants = visitor.getConstants();
5626                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5627
5628                                if (functions != null && !functions.isEmpty()) {
5629                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
5630                                }
5631                                if (subquerys != null && !subquerys.isEmpty()) {
5632                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
5633                                }
5634                                if (objectNames != null && !objectNames.isEmpty()) {
5635                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
5636                                }
5637                                if (constants != null && !constants.isEmpty()) {
5638                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
5639                                }
5640                                
5641                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
5642                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
5643                                }
5644                        }
5645                }
5646
5647                if(stmt.getAssignments()!=null){
5648                        for (int i = 0; i < stmt.getAssignments().size(); i++) {
5649                                TSetAssignment assignStmt = stmt.getAssignments().getElement(i);
5650                                analyzeSetAssignmentStmt(assignStmt);
5651                        }
5652                }
5653        }
5654
5655        private void analyzeSetAssignmentStmt(TSetAssignment stmt) {
5656                TExpression right = stmt.getParameterValue();
5657                TObjectName columnObject = stmt.getParameterName();
5658                if (columnObject != null) {
5659                        TableColumn tableColumn = null;
5660                        Variable tableModel;
5661                        if (columnObject.toString().indexOf(".") != -1) {
5662                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
5663                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
5664                        } else {
5665                                tableModel = modelFactory.createVariable(columnObject);
5666                        }
5667                        tableModel.setCreateTable(true);
5668                        tableModel.setSubType(SubType.record);
5669                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
5670                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
5671                        } else {
5672                                tableColumn = tableModel.getColumns().get(0);
5673                        }
5674
5675                        if (tableColumn != null && right!=null) {
5676                                columnsInExpr visitor = new columnsInExpr();
5677                                right.inOrderTraverse(visitor);
5678                                List<TObjectName> objectNames = visitor.getObjectNames();
5679                                List<TParseTreeNode> functions = visitor.getFunctions();
5680                                List<TParseTreeNode> constants = visitor.getConstants();
5681                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5682
5683                                if (functions != null && !functions.isEmpty()) {
5684                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
5685                                }
5686                                if (subquerys != null && !subquerys.isEmpty()) {
5687                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
5688                                }
5689                                if (objectNames != null && !objectNames.isEmpty()) {
5690                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
5691                                }
5692                                if (constants != null && !constants.isEmpty()) {
5693                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
5694                                }
5695
5696                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
5697                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
5698                                }
5699                        }
5700                }
5701        }
5702
5703        private void analyzeMssqlSetStmt(TMssqlSet stmt) {
5704                TExpression right = stmt.getVarExpr();
5705                TObjectName columnObject = stmt.getVarName();
5706                if (columnObject != null) {
5707                        TableColumn tableColumn = null;
5708                        Variable tableModel;
5709                        if (columnObject.toString().indexOf(".") != -1) {
5710                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
5711                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
5712                        } else {
5713                                tableModel = modelFactory.createVariable(columnObject);
5714                        }
5715                        tableModel.setCreateTable(true);
5716                        tableModel.setSubType(SubType.record);
5717                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
5718                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
5719                        }
5720                        else {
5721                                tableColumn = tableModel.getColumns().get(0);
5722                        }
5723
5724                        if (tableColumn != null && right!=null) {
5725                                columnsInExpr visitor = new columnsInExpr();
5726                                right.inOrderTraverse(visitor);
5727                                List<TObjectName> objectNames = visitor.getObjectNames();
5728                                List<TParseTreeNode> functions = visitor.getFunctions();
5729                                List<TParseTreeNode> constants = visitor.getConstants();
5730                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5731
5732                                if (functions != null && !functions.isEmpty()) {
5733                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
5734                                }
5735                                if (subquerys != null && !subquerys.isEmpty()) {
5736                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
5737                                }
5738                                if (objectNames != null && !objectNames.isEmpty()) {
5739                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
5740                                }
5741                                if (constants != null && !constants.isEmpty()) {
5742                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
5743                                }
5744
5745                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
5746                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
5747                                }
5748                        }
5749                        else if(tableColumn!=null && stmt.getSubquery()!=null){
5750                                analyzeCustomSqlStmt(stmt.getSubquery());
5751                                analyzeSubqueryDataFlowRelation(tableColumn, Arrays.asList(stmt.getSubquery()), EffectType.select);
5752                        }
5753                }
5754        }
5755
5756        private void analyzeAssignStmt(TAssignStmt stmt) {
5757                TExpression left = stmt.getLeft();
5758                TExpression right = stmt.getExpression();
5759                TObjectName columnObject = null;
5760                if (left == null) {
5761                        columnObject = stmt.getVariableName();
5762                } else if (left.getExpressionType() == EExpressionType.simple_object_name_t) {
5763                        columnObject = left.getObjectOperand();
5764                }
5765                if (columnObject != null) {
5766                        TableColumn tableColumn = null;
5767                        if (columnObject.getDbObjectType() == EDbObjectType.variable || stmt.getVariableName() != null) {
5768                                Variable tableModel;
5769                                if (columnObject.toString().indexOf(".") != -1) {
5770                                        List<String> splits = SQLUtil.parseNames(columnObject.toString());
5771                                        tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
5772                                } else {
5773                                        tableModel = modelFactory.createVariable(columnObject);
5774                                }
5775                                tableModel.setCreateTable(true);
5776                                tableModel.setSubType(SubType.record);
5777                                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
5778                                        tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
5779                                } else {
5780                                        tableColumn = tableModel.getColumns().get(0);
5781                                }
5782                        } else {
5783                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
5784                                if (splits.size() > 1) {
5785                                        Table tableModel = modelManager
5786                                                        .getTableByName(DlineageUtil.getTableFullName(splits.get(splits.size() - 2)));
5787                                        if (tableModel == null) {
5788                                                String procedureName = DlineageUtil.getProcedureParentName(stmt);
5789                                                String variableString = splits.get(splits.size() - 2).toString();
5790                                                if (variableString.startsWith(":")) {
5791                                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
5792                                                }
5793                                                if (!SQLUtil.isEmpty(procedureName)) {
5794                                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
5795                                                }
5796                                                tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
5797                                        }
5798                                        if (tableModel != null) {
5799                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
5800                                        }
5801                                }
5802                        }
5803
5804                        if (tableColumn != null) {
5805                                columnsInExpr visitor = new columnsInExpr();
5806                                right.inOrderTraverse(visitor);
5807                                List<TObjectName> objectNames = visitor.getObjectNames();
5808                                List<TParseTreeNode> functions = visitor.getFunctions();
5809                                List<TParseTreeNode> constants = visitor.getConstants();
5810                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5811
5812                                if (functions != null && !functions.isEmpty()) {
5813                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
5814                                }
5815                                if (subquerys != null && !subquerys.isEmpty()) {
5816                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
5817                                }
5818                                if (objectNames != null && !objectNames.isEmpty()) {
5819                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
5820                                }
5821                                if (constants != null && !constants.isEmpty()) {
5822                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
5823                                }
5824                        }
5825                }
5826        }
5827
5828        private void analyzeOpenForStmt(TOpenforStmt stmt) {
5829                if (stmt.getSubquery() == null) {
5830                        return;
5831                }
5832
5833                Variable cursorTempTable = modelFactory.createCursor(stmt);
5834                cursorTempTable.setVariable(true);
5835                cursorTempTable.setSubType(SubType.cursor);
5836                modelManager.bindCursorModel(stmt, cursorTempTable);
5837                analyzeSelectStmt(stmt.getSubquery());
5838
5839                TableColumn cursorColumn = null;
5840                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
5841                        TObjectName starColumn = new TObjectName();
5842                        starColumn.setString("*");
5843                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
5844                } else {
5845                        cursorColumn = cursorTempTable.getColumns().get(0);
5846                }
5847
5848                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
5849                if (resultSetModel != null) {
5850                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
5851                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
5852                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5853                                dataflowRelation.setEffectType(EffectType.cursor);
5854                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
5855                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
5856                        }
5857                }
5858        }
5859
5860        private void analyzeCursorDeclStmt(TCursorDeclStmt stmt) {
5861                if (stmt.getSubquery() == null) {
5862                        return;
5863                }
5864
5865                Variable cursorTempTable = modelFactory.createCursor(stmt);
5866                cursorTempTable.setVariable(true);
5867                cursorTempTable.setSubType(SubType.cursor);
5868                modelManager.bindCursorModel(stmt, cursorTempTable);
5869                analyzeSelectStmt(stmt.getSubquery());
5870
5871                TableColumn cursorColumn = null;
5872                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
5873                        TObjectName starColumn = new TObjectName();
5874                        starColumn.setString("*");
5875                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
5876                } else {
5877                        cursorColumn = cursorTempTable.getColumns().get(0);
5878                }
5879
5880                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
5881                if (resultSetModel != null) {
5882                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
5883                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
5884                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5885                                dataflowRelation.setEffectType(EffectType.cursor);
5886                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
5887                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
5888                        }
5889                }
5890        }
5891
5892        private void analyzeDb2Declare(TDb2SqlVariableDeclaration stmt) {
5893                TDeclareVariableList variables = stmt.getVariables();
5894                if (variables == null) {
5895                        return;
5896                }
5897                for (int i = 0; i < variables.size(); i++) {
5898                        TDeclareVariable variable = variables.getDeclareVariable(i);
5899                        if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) {
5900
5901
5902                                TObjectName tableName = variable.getVariableName();
5903                                TTableElementList columns = variable.getTableTypeDefinitions();
5904
5905                                Table tableModel = modelFactory.createTableByName(tableName, true);
5906                                tableModel.setCreateTable(true);
5907                                String procedureParent = getProcedureParentName(stmt);
5908                                if (procedureParent != null) {
5909                                        tableModel.setParent(procedureParent);
5910                                }
5911                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
5912
5913                                for (int j = 0; j < columns.size(); j++) {
5914                                        TTableElement tableElement = columns.getTableElement(j);
5915                                        TColumnDefinition column = tableElement.getColumnDefinition();
5916                                        if (column != null && column.getColumnName() != null) {
5917                                                modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
5918                                        }
5919                                }
5920                        } else if (variable.getVariableName() != null) {
5921                                Variable cursorVariable = modelFactory.createVariable(variable.getVariableName());
5922                                cursorVariable.setCreateTable(true);
5923                                cursorVariable.setSubType(SubType.record);
5924                                if(variable.getDatatype()!=null && isSimpleDataType(variable.getDatatype())){
5925                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable,
5926                                                        variable.getVariableName(), true);
5927                                }
5928                                else {
5929                                        TObjectName variableProperties = new TObjectName();
5930                                        variableProperties.setString("*");
5931                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable,
5932                                                        variableProperties, true);
5933                                }
5934                        }
5935                }
5936        }
5937
5938        private void analyzeMssqlDeclare(TMssqlDeclare stmt) {
5939                if (stmt.getDeclareType() == EDeclareType.variable) {
5940                        TDeclareVariableList variables = stmt.getVariables();
5941                        if (variables == null) {
5942                                return;
5943                        }
5944                        for (int i = 0; i < variables.size(); i++) {
5945                                TDeclareVariable variable = variables.getDeclareVariable(i);
5946                                if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) {
5947
5948
5949                                        TObjectName tableName = variable.getVariableName();
5950                                        TTableElementList columns = variable.getTableTypeDefinitions();
5951
5952                                        Table tableModel = modelFactory.createTableByName(tableName, true);
5953                                        tableModel.setCreateTable(true);
5954                                        String procedureParent = getProcedureParentName(stmt);
5955                                        if (procedureParent != null) {
5956                                                tableModel.setParent(procedureParent);
5957                                        }
5958                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
5959
5960                                        for (int j = 0; j < columns.size(); j++) {
5961                                                TTableElement tableElement = columns.getTableElement(j);
5962                                                TColumnDefinition column = tableElement.getColumnDefinition();
5963                                                if (column != null && column.getColumnName() != null) {
5964                                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
5965                                                }
5966                                        }
5967                                } else if (variable.getVariableName() != null) {
5968                                        Variable cursorVariable = modelFactory.createVariable(variable.getVariableName());
5969                                        cursorVariable.setCreateTable(true);
5970                                        cursorVariable.setSubType(SubType.record);
5971                                        TableColumn variableProperty = null;
5972                                        if (variable.getDatatype() != null && isSimpleDataType(variable.getDatatype())) {
5973                                                variableProperty = modelFactory.createTableColumn(cursorVariable, variable.getVariableName(),
5974                                                                true);
5975                                        } else {
5976                                                TObjectName variableProperties = new TObjectName();
5977                                                variableProperties.setString("*");
5978                                                variableProperty = modelFactory.createTableColumn(cursorVariable, variableProperties, true);
5979                                        }
5980                                        
5981                                        if (variable.getDefaultValue() != null && variable.getDefaultValue().getSubQuery() != null) {
5982                                                analyzeSelectStmt(variable.getDefaultValue().getSubQuery());
5983                                                ResultSet resultSetModel = (ResultSet) modelManager
5984                                                                .getModel(variable.getDefaultValue().getSubQuery());
5985                                                if (variableProperty != null && resultSetModel != null) {
5986                                                        for (ResultColumn column : resultSetModel.getColumns()) {
5987                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5988                                                                dataflowRelation.setEffectType(EffectType.select);
5989                                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(column));
5990                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5991                                                        }
5992                                                }
5993                                        }
5994                                }
5995                        }
5996                } else if (stmt.getDeclareType() == EDeclareType.cursor) {
5997                        Variable cursorTempTable = modelFactory.createCursor(stmt);
5998                        cursorTempTable.setVariable(true);
5999                        cursorTempTable.setSubType(SubType.cursor);
6000                        modelManager.bindCursorModel(stmt, cursorTempTable);
6001                        analyzeSelectStmt(stmt.getSubquery());
6002                        ResultSet resultSetModel = (ResultSet)modelManager.getModel(stmt.getSubquery());
6003                        if (resultSetModel != null && resultSetModel.isDetermined()) {
6004                                for(ResultColumn resultColumn: resultSetModel.getColumns()){
6005                                        TObjectName starColumn = new TObjectName();
6006                                        starColumn.setString(resultColumn.getName());
6007                                        TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6008                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6009                                        dataflowRelation.setEffectType(EffectType.cursor);
6010                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6011                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6012                                }
6013                        }
6014                        else {
6015                                TableColumn cursorColumn = null;
6016                                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6017                                        TObjectName starColumn = new TObjectName();
6018                                        starColumn.setString("*");
6019                                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6020                                        cursorColumn.setShowStar(false);
6021                                        cursorColumn.setExpandStar(true);
6022                                } else {
6023                                        cursorColumn = cursorTempTable.getColumns().get(0);
6024                                }
6025
6026                                if (resultSetModel != null) {
6027                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6028                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6029                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6030                                                dataflowRelation.setEffectType(EffectType.cursor);
6031                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6032                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6033                                        }
6034                                }
6035                        }
6036                }
6037        }
6038
6039
6040        private boolean analyzeMssqlJsonDeclare(TMssqlDeclare stmt, String jsonName, Table jsonTable) {
6041                TDeclareVariableList variables = stmt.getVariables();
6042                if (variables == null) {
6043                        return false;
6044                }
6045                for (int i = 0; i < variables.size(); i++) {
6046                        TDeclareVariable variable = variables.getDeclareVariable(i);
6047                        TObjectName variableName = variable.getVariableName();
6048                        if (DlineageUtil.getIdentifierNormalTableName(variableName.toString())
6049                                        .equals(DlineageUtil.getIdentifierNormalTableName(jsonName))) {
6050                                if (variable.getDefaultValue() != null) {
6051                                        Table variableTable = modelFactory.createJsonVariable(variableName);
6052                                        variableTable.setVariable(true);
6053                                        variableTable.setSubType(SubType.scalar);
6054                                        variableTable.setCreateTable(true);
6055                                        TableColumn property = modelFactory.createVariableProperty(variableTable, variable);
6056
6057                                        for (int j = 0; j < jsonTable.getColumns().size(); j++) {
6058                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6059                                                relation.setEffectType(EffectType.select);
6060                                                relation.setTarget(new TableColumnRelationshipElement(jsonTable.getColumns().get(j)));
6061                                                relation.addSource(new TableColumnRelationshipElement(property));
6062                                        }
6063                                }
6064                                return true;
6065                        }
6066                }
6067                return false;
6068        }
6069
6070        private void analyzeCreateTableStmt(TCreateTableSqlStatement stmt) {
6071                if (stmt.getCloneSourceTable() != null) {
6072                        analyzeCloneTableStmt(stmt);
6073                        return;
6074                }
6075
6076                TTable table = stmt.getTargetTable();
6077
6078                boolean hasDefinition = false;
6079
6080                if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
6081                        hasDefinition = true;
6082                }
6083
6084                if (table != null) {
6085                        Table tableModel = modelFactory.createTableFromCreateDDL(table, hasDefinition || stmt.getSubQuery() == null
6086                                        || (stmt.getSubQuery().getSetOperatorType() == ESetOperatorType.none && stmt.getSubQuery().getResultColumnList().toString().indexOf("*") == -1));
6087                        if (stmt.isExternal()) {
6088                                tableModel.setExternal(true);
6089                        }
6090
6091                        if (stmt.getSubQuery() != null) {
6092                                Process process = modelFactory.createProcess(stmt);
6093                                tableModel.addProcess(process);
6094                        }
6095
6096                        String procedureParent = getProcedureParentName(stmt);
6097                        if (procedureParent != null) {
6098                                tableModel.setParent(procedureParent);
6099                        }
6100
6101                        if (hasDefinition) {
6102                                if(stmt.getSubQuery()!=null) {
6103                                        TSelectSqlStatement subquery = stmt.getSubQuery();
6104                                        analyzeSelectStmt(subquery);
6105                                        Process process = modelFactory.createProcess(stmt);
6106                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
6107                                        if(resultSetModel.isDetermined()){
6108                                                tableModel.setFromDDL(true);
6109                                        }
6110                                        if (resultSetModel != null) {
6111                                                int resultSetSize = resultSetModel.getColumns().size();
6112                                                int stmtColumnSize = stmt.getColumnList().size();
6113                                                int j = 0;
6114                                                int tableColumnSize = stmtColumnSize;
6115                                                if (resultSetModel.isDetermined() && resultSetSize > tableColumnSize) {
6116                                                        tableColumnSize = resultSetSize;
6117                                                }
6118                                                for (int i = 0; i < tableColumnSize && j < resultSetSize; i++) {
6119                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
6120                                                        if (i < stmtColumnSize) {
6121                                                                TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName();
6122                                                                
6123                                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
6124                                                                        j++;
6125                                                                } else {
6126                                                                        if (resultSetSize - j == stmt.getColumnList().size() - i) {
6127                                                                                j++;
6128                                                                        }
6129                                                                }
6130
6131                                                                if (alias != null) {
6132                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true);
6133                                                                        if (resultColumn != null) {
6134                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6135                                                                                relation.setEffectType(EffectType.create_table);
6136                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6137                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6138                                                                                relation.setProcess(process);
6139                                                                        }
6140                                                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
6141                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel,
6142                                                                                        (TObjectName) resultColumn.getColumnObject(), true);
6143                                                                        if (resultColumn != null) {
6144                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6145                                                                                relation.setEffectType(EffectType.create_table);
6146                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6147                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6148                                                                                relation.setProcess(process);
6149                                                                        }
6150                                                                } else if (resultColumn.getColumnObject() instanceof TResultColumn) {
6151                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel,
6152                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), true);
6153                                                                        ResultColumn column = (ResultColumn) modelManager
6154                                                                                        .getModel(resultColumn.getColumnObject());
6155                                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
6156                                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
6157                                                                        }
6158                                                                        if (resultColumn != null) {
6159                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6160                                                                                relation.setEffectType(EffectType.create_table);
6161                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6162                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6163                                                                                relation.setProcess(process);
6164                                                                        }
6165                                                                }
6166                                                        }
6167                                                        else if(resultSetModel.isDetermined()){
6168                                                                TObjectName tableName = new TObjectName();
6169                                                                tableName.setString(resultColumn.getName());
6170                                                                TableColumn viewColumn = modelFactory.createTableColumn(tableModel, tableName, true);
6171                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6172                                                                relation.setEffectType(EffectType.create_table);
6173                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6174                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6175                                                                relation.setProcess(process);
6176                                                                j++;
6177                                                        }
6178                                                }
6179                                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
6180                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
6181                                                        impactRelation.setEffectType(EffectType.create_table);
6182                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
6183                                                                        resultSetModel.getRelationRows()));
6184                                                        impactRelation.setTarget(
6185                                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
6186                                                }
6187                                        }
6188
6189                                        if (subquery.getResultColumnList() == null && subquery.getValueClause() != null
6190                                                        && subquery.getValueClause().getValueRows().size() == stmt.getColumnList().size()) {
6191                                                for (int i = 0; i < stmt.getColumnList().size(); i++) {
6192                                                        TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName();
6193
6194                                                        if (alias != null) {
6195                                                                TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true);
6196
6197                                                                TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr();
6198
6199                                                                columnsInExpr visitor = new columnsInExpr();
6200                                                                expression.inOrderTraverse(visitor);
6201                                                                List<TObjectName> objectNames = visitor.getObjectNames();
6202                                                                List<TParseTreeNode> functions = visitor.getFunctions();
6203
6204                                                                if (functions != null && !functions.isEmpty()) {
6205                                                                        analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select);
6206
6207                                                                }
6208
6209                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6210                                                                if (subquerys != null && !subquerys.isEmpty()) {
6211                                                                        analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select);
6212                                                                }
6213
6214                                                                analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions);
6215                                                                List<TParseTreeNode> constants = visitor.getConstants();
6216                                                                analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions);
6217                                                        }
6218                                                }
6219                                        }
6220                                        
6221                                        return;
6222                                }
6223                                else {
6224                                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
6225                                                TColumnDefinition column = stmt.getColumnList().getColumn(i);
6226                                                if (column.getDatatype() != null && column.getDatatype().getTypeOfList() != null
6227                                                                && column.getDatatype().getTypeOfList().getColumnDefList() != null) {
6228                                                        for (int j = 0; j < column.getDatatype().getTypeOfList().getColumnDefList().size(); j++) {
6229                                                                TObjectName columnName = new TObjectName();
6230                                                                if (column.getDatatype().getDataType() == EDataType.array_t) {
6231                                                                        columnName.setString(column.getColumnName().getColumnNameOnly() + ".array."
6232                                                                                        + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6233                                                                                                        .getColumnName().getColumnNameOnly());
6234                                                                } else {
6235                                                                        columnName.setString(column.getColumnName().getColumnNameOnly() + "."
6236                                                                                        + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6237                                                                                                        .getColumnName().getColumnNameOnly());
6238                                                                }
6239                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName,
6240                                                                                hasDefinition);
6241                                                                tableColumn.setStruct(true);
6242                                                                tableColumn.setColumnIndex(i);
6243                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6244                                                                
6245                                                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
6246                                                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
6247                                                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
6248                                                                        crudRelationship.setEffectType(EffectType.create_table);
6249                                                                }
6250                                                        }
6251                                                        continue;
6252                                                }
6253                                                if (column.getDatatype() != null && column.getDatatype().getColumnDefList() != null) {
6254                                                        Stack<TColumnDefinition> columnPaths = new Stack<TColumnDefinition>();
6255                                                        flattenStructColumns(hasDefinition, tableModel, column, columnPaths, i);
6256                                                        continue;
6257                                                }
6258                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column.getColumnName(),
6259                                                                hasDefinition);
6260                                                if (tableColumn == null) {
6261                                                        continue;
6262                                                }
6263                                                
6264                                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
6265                                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
6266                                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
6267                                                        crudRelationship.setEffectType(EffectType.create_table);
6268                                                }
6269                                                
6270                                                if (column.getDatatype() != null && column.getDatatype().getDataType() == EDataType.variant_t) {
6271                                                        if (tableColumn != null) {
6272                                                                tableColumn.setVariant(true);
6273                                                        }
6274                                                }
6275                                                if (column.getDatatype() != null) {
6276                                                        String dType = column.getDatatype().getDataTypeName();
6277                                                        if ((!SQLUtil.isEmpty(dType)) && (dType.indexOf("_") > 0)) {
6278                                                                dType = dType.split("_")[0];
6279                                                        }
6280                                                        tableColumn.setDataType(dType);
6281                                                }
6282                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6283                                        }
6284                                }
6285                        }
6286
6287                        if (stmt.getExternalTableOption("DATA_SOURCE") != null) {
6288                                String dataSourceName = stmt.getExternalTableOption("DATA_SOURCE");
6289                                Table dataSource = modelManager.getTableByName(DlineageUtil.getTableFullName(dataSourceName));
6290                                if (dataSource != null) {
6291                                        TableColumn dataSourceColumn = dataSource.getColumns().get(0);
6292                                        for (int i = 0; i < tableModel.getColumns().size(); i++) {
6293                                                TableColumn column = tableModel.getColumns().get(i);
6294                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6295                                                relation.setTarget(new TableColumnRelationshipElement(column));
6296                                                relation.addSource(new TableColumnRelationshipElement(dataSourceColumn));
6297
6298                                                appendTableColumnToSQLEnv(tableModel, column);
6299                                        }
6300                                }
6301                        }
6302
6303                        if (stmt.getSubQuery() != null) {
6304
6305                                analyzeSelectStmt(stmt.getSubQuery());
6306
6307                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
6308                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
6309                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
6310                                        impactRelation.setEffectType(EffectType.create_table);
6311                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
6312                                                        resultSetModel.getRelationRows()));
6313                                        impactRelation.setTarget(
6314                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
6315                                }
6316                        }
6317
6318                        if (stmt.getSubQuery() != null && !stmt.getSubQuery().isCombinedQuery()) {
6319                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
6320                                                .getModel(stmt.getSubQuery().getResultColumnList());
6321                                if(resultSetModel.isDetermined()){
6322                                        tableModel.setDetermined(true);
6323                                        tableModel.setFromDDL(true);
6324                                }
6325                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6326                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6327                                        if (resultSetModel.isDetermined() && resultColumn.getName().endsWith("*")) {
6328                                                continue;
6329                                        }
6330
6331                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
6332                                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
6333
6334                                                TAliasClause alias = columnObject.getAliasClause();
6335                                                if (alias != null && alias.getAliasName() != null) {
6336                                                        TableColumn tableColumn = null;
6337                                                        if (!hasDefinition) {
6338                                                                tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(),
6339                                                                                !hasDefinition);
6340                                                        } else {
6341                                                                tableColumn = tableModel.getColumns().get(i);
6342                                                        }
6343
6344                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6345                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6346                                                        }
6347
6348                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6349                                                        relation.setEffectType(EffectType.create_table);
6350                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6351                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6352                                                        Process process = modelFactory.createProcess(stmt);
6353                                                        relation.setProcess(process);
6354                                                } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) {
6355                                                        TableColumn tableColumn = null;
6356                                                        TObjectName columnObj = columnObject.getFieldAttr();
6357                                                        if(columnObj == null) {
6358                                                                columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand();
6359                                                        }
6360                                                        if ((columnObj == null || columnObj.toString().endsWith("*")) && !resultColumn.getName().endsWith("*")) {
6361                                                                columnObj = new TObjectName();
6362                                                                columnObj.setString(resultColumn.getName());
6363                                                        }
6364
6365                                                        if(columnObj == null){
6366                                                                logger.info("Can't handle column " + resultColumn.getName());
6367                                                                continue;
6368                                                        }
6369
6370                                                        if (!hasDefinition) {
6371                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObj,
6372                                                                                !hasDefinition);
6373                                                                if (tableColumn == null) {
6374                                                                        if (tableModel.getColumns().isEmpty()) {
6375                                                                                logger.info("Add table " + tableModel.getName() + " column " + columnObj.toString() + " failed");
6376                                                                        }
6377                                                                        else if (resultColumn.getName().endsWith("*")) {
6378                                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
6379                                                                                        tableColumn = tableModel.getColumns().get(j);
6380                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6381                                                                                        relation.setEffectType(EffectType.create_table);
6382                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6383                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6384                                                                                        if (tableColumn.getName().endsWith("*")
6385                                                                                                        && resultColumn.getName().endsWith("*")) {
6386                                                                                                tableModel.setStarStmt("create_table");
6387                                                                                        }
6388                                                                                        Process process = modelFactory.createProcess(stmt);
6389                                                                                        relation.setProcess(process);
6390                                                                                }
6391                                                                        }
6392                                                                        continue;
6393                                                                }
6394                                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6395                                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
6396                                                                }
6397
6398                                                                Object model = modelManager
6399                                                                                .getModel(resultColumn.getColumnObject());
6400                                                                if (model instanceof ResultColumn) {
6401                                                                        ResultColumn column = (ResultColumn) model;
6402                                                                        if (tableColumn.getName().endsWith("*") && column != null
6403                                                                                        && !column.getStarLinkColumns().isEmpty()) {
6404                                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
6405                                                                        }
6406
6407                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6408                                                                        relation.setEffectType(EffectType.create_table);
6409                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6410                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6411                                                                        if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
6412                                                                                tableModel.setStarStmt("create_table");
6413                                                                        }
6414                                                                        Process process = modelFactory.createProcess(stmt);
6415                                                                        relation.setProcess(process);
6416                                                                }
6417                                                                else if(model instanceof LinkedHashMap) {
6418                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
6419                                                                        LinkedHashMap<String, ResultColumn> resultColumns =  (LinkedHashMap<String, ResultColumn>)model;
6420                                                                        if (columnObj.toString().endsWith("*")) {
6421                                                                                for (String key : resultColumns.keySet()) {
6422                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName());
6423                                                                                        DataFlowRelationship relation = modelFactory
6424                                                                                                        .createDataFlowRelation();
6425                                                                                        relation.setEffectType(EffectType.create_table);
6426                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6427                                                                                        relation.addSource(
6428                                                                                                        new ResultColumnRelationshipElement(resultColumns.get(key)));
6429                                                                                        Process process = modelFactory.createProcess(stmt);
6430                                                                                        relation.setProcess(process);
6431                                                                                }
6432                                                                        } else if (resultColumns.containsKey(columnName)) {
6433                                                                                ResultColumn column = resultColumns.get(columnName);
6434                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName());
6435                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6436                                                                                relation.setEffectType(EffectType.create_table);
6437                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6438                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
6439                                                                                Process process = modelFactory.createProcess(stmt);
6440                                                                                relation.setProcess(process);
6441                                                                        }
6442                                                                }
6443                                                        } else {
6444                                                                if (resultColumn.getName().endsWith("*")) {
6445                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
6446                                                                                tableColumn = tableModel.getColumns().get(j);
6447                                                                                ResultColumn column = (ResultColumn) modelManager
6448                                                                                                .getModel(resultColumn.getColumnObject());
6449                                                                                if (tableColumn.getName().endsWith("*") && column != null
6450                                                                                                && !column.getStarLinkColumns().isEmpty()) {
6451                                                                                        tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
6452                                                                                }
6453
6454                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6455                                                                                relation.setEffectType(EffectType.create_table);
6456                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6457                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6458                                                                                if (tableColumn.getName().endsWith("*")
6459                                                                                                && resultColumn.getName().endsWith("*")) {
6460                                                                                        tableModel.setStarStmt("create_table");
6461                                                                                        ;
6462                                                                                }
6463                                                                                Process process = modelFactory.createProcess(stmt);
6464                                                                                relation.setProcess(process);
6465                                                                        }
6466                                                                } else {
6467                                                                        tableColumn = tableModel.getColumns().get(i);
6468                                                                        Object model = modelManager
6469                                                                                        .getModel(resultColumn.getColumnObject());
6470                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
6471                                                                        if(model instanceof LinkedHashMap) {
6472                                                                                LinkedHashMap<String, ResultColumn> resultColumns =  (LinkedHashMap<String, ResultColumn>)model;
6473                                                                                if (resultColumns.size() == tableModel.getColumns().size()) {
6474                                                                                        int j = 0;
6475                                                                                        for (String key : resultColumns.keySet()) {
6476                                                                                                if (j == i) {
6477                                                                                                        ResultColumn column = resultColumns.get(key);
6478                                                                                                        DataFlowRelationship relation = modelFactory
6479                                                                                                                        .createDataFlowRelation();
6480                                                                                                        relation.setEffectType(EffectType.create_table);
6481                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6482                                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
6483                                                                                                        Process process = modelFactory.createProcess(stmt);
6484                                                                                                        relation.setProcess(process);
6485                                                                                                }
6486                                                                                                j++;
6487                                                                                        }
6488                                                                                } else if (resultColumns.containsKey(columnName)) {
6489                                                                                        ResultColumn column = resultColumns.get(columnName);
6490                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName());
6491                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6492                                                                                        relation.setEffectType(EffectType.create_table);
6493                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6494                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
6495                                                                                        Process process = modelFactory.createProcess(stmt);
6496                                                                                        relation.setProcess(process);
6497                                                                                } else {
6498                                                                                        throw new UnsupportedOperationException("Can't handle this star case.");
6499                                                                                }
6500                                                                        }
6501                                                                        else if (model instanceof ResultColumn) {
6502                                                                                ResultColumn column = (ResultColumn) modelManager
6503                                                                                                .getModel(resultColumn.getColumnObject());
6504                                                                                if (tableColumn.getName().endsWith("*") && column != null
6505                                                                                                && !column.getStarLinkColumns().isEmpty()) {
6506                                                                                        tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
6507                                                                                }
6508
6509                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6510                                                                                relation.setEffectType(EffectType.create_table);
6511                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6512                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6513                                                                                if (tableColumn.getName().endsWith("*")
6514                                                                                                && resultColumn.getName().endsWith("*")) {
6515                                                                                        tableModel.setStarStmt("create_table");
6516                                                                                }
6517                                                                                Process process = modelFactory.createProcess(stmt);
6518                                                                                relation.setProcess(process);
6519                                                                        }
6520                                                                }
6521                                                        }
6522                                                } else {
6523                                                        TableColumn tableColumn = null;
6524                                                        if (!hasDefinition) {
6525                                                                TObjectName columnName = new TObjectName();
6526                                                                columnName.setString(resultColumn.getColumnObject().toString());
6527                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName, !hasDefinition);
6528                                                                if(tableColumn == null){
6529                                                                        continue;
6530                                                                }
6531                                                        } else {
6532                                                                tableColumn = tableModel.getColumns().get(i);
6533                                                        }
6534                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
6535                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
6536                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
6537                                                        }
6538
6539                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6540                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6541                                                        }
6542
6543                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6544                                                        relation.setEffectType(EffectType.create_table);
6545                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6546                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6547                                                        Process process = modelFactory.createProcess(stmt);
6548                                                        relation.setProcess(process);
6549                                                }
6550                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
6551                                                TableColumn tableColumn = null;
6552                                                if (!hasDefinition) {
6553                                                        tableColumn = modelFactory.createTableColumn(tableModel,
6554                                                                        (TObjectName) resultColumn.getColumnObject(), !hasDefinition);
6555                                                } else {
6556                                                        tableColumn = tableModel.getColumns().get(i);
6557                                                }
6558
6559                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6560                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
6561                                                }
6562
6563                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6564                                                relation.setEffectType(EffectType.create_table);
6565                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6566                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6567                                                Process process = modelFactory.createProcess(stmt);
6568                                                relation.setProcess(process);
6569                                        }
6570                                }
6571                        } else if (stmt.getSubQuery() != null) {
6572                                SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(stmt.getSubQuery());
6573                                if(resultSetModel.isDetermined()){
6574                                        tableModel.setDetermined(true);
6575                                        tableModel.setFromDDL(true);
6576                                }
6577                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6578                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6579                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
6580                                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
6581
6582                                                TAliasClause alias = columnObject.getAliasClause();
6583                                                if (alias != null && alias.getAliasName() != null) {
6584                                                        TableColumn tableColumn = null;
6585                                                        if (!hasDefinition) {
6586                                                                tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(),
6587                                                                                !hasDefinition);
6588                                                                if (tableColumn == null) {
6589                                                                        continue;
6590                                                                }
6591                                                        } else {
6592                                                                tableColumn = tableModel.getColumns().get(i);
6593                                                        }
6594
6595                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6596                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6597                                                        }
6598
6599                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6600                                                        relation.setEffectType(EffectType.create_table);
6601                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6602                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6603                                                        Process process = modelFactory.createProcess(stmt);
6604                                                        relation.setProcess(process);
6605                                                } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) {
6606                                                        TableColumn tableColumn = null;
6607                                                        TObjectName columnObj = columnObject.getFieldAttr();
6608                                                        if(columnObj == null) {
6609                                                                columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand();
6610                                                        }
6611                                                        if (!hasDefinition) {
6612                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObj,
6613                                                                                !hasDefinition);
6614                                                                if (tableColumn == null) {
6615                                                                        continue;
6616                                                                }
6617                                                        } else {
6618                                                                tableColumn = tableModel.getColumns().get(i);
6619                                                        }
6620                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
6621                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
6622                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
6623                                                        }
6624
6625                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6626                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6627                                                        }
6628
6629                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6630                                                        relation.setEffectType(EffectType.create_table);
6631                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6632                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6633                                                        Process process = modelFactory.createProcess(stmt);
6634                                                        relation.setProcess(process);
6635                                                } else {
6636                                                        ErrorInfo errorInfo = new ErrorInfo();
6637                                                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
6638                                                        errorInfo.setErrorMessage("Can't handle the table column " + columnObject.toString());
6639                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(
6640                                                                        columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo,
6641                                                                        ModelBindingManager.getGlobalHash()));
6642                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo,
6643                                                                        columnObject.getEndToken().columnNo + columnObject.getEndToken().astext.length(),
6644                                                                        ModelBindingManager.getGlobalHash()));
6645                                                        errorInfos.add(errorInfo);
6646                                                        continue;
6647                                                }
6648                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
6649                                                TableColumn tableColumn = null;
6650                                                if (!hasDefinition) {
6651                                                        tableColumn = modelFactory.createTableColumn(tableModel,
6652                                                                        (TObjectName) resultColumn.getColumnObject(), !hasDefinition);
6653                                                } else {
6654                                                        tableColumn = tableModel.getColumns().get(i);
6655                                                }
6656
6657                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6658                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
6659                                                }
6660
6661                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6662                                                relation.setEffectType(EffectType.create_table);
6663                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6664                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6665                                                Process process = modelFactory.createProcess(stmt);
6666                                                relation.setProcess(process);
6667                                        }
6668                                }
6669                        } else if (stmt.getLikeTableName() != null) {
6670                                Table likeTableModel = modelFactory.createTableByName(stmt.getLikeTableName());
6671
6672                                if(likeTableModel.isCreateTable()){
6673                                        for(TableColumn column: likeTableModel.getColumns()){
6674                                                TObjectName tableColumn = new TObjectName();
6675                                                tableColumn.setString(column.getName());
6676                                                TableColumn createTableColumn = modelFactory.createTableColumn(tableModel, tableColumn, true);
6677                                                createTableColumn.setPrimaryKey(column.getPrimaryKey());
6678                                                createTableColumn.setForeignKey(column.getForeignKey());
6679                                                createTableColumn.setIndexKey(column.getIndexKey());
6680                                                createTableColumn.setUnqiueKey(column.getUnqiueKey());
6681                                                createTableColumn.setDataType(column.getDataType());
6682                                        }
6683                                        tableModel.setCreateTable(true);
6684                                }
6685
6686//                              Process process = modelFactory.createProcess(stmt);
6687//                              process.setType("Like Table");
6688//                              tableModel.addProcess(process);
6689//
6690//
6691//                              DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6692//                              relation.setEffectType(EffectType.like_table);
6693//                              relation.setTarget(
6694//                                              new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
6695//                              relation.addSource(
6696//                                              new RelationRowsRelationshipElement<TableRelationRows>(likeTableModel.getRelationRows()));
6697//                              relation.setProcess(process);
6698                        }
6699
6700                        if (stmt.getStageLocation() != null && stmt.getStageLocation().getStageName() != null) {
6701                                tableModel
6702                                                .setLocation(DlineageUtil.getTableFullName(stmt.getStageLocation().getStageName().toString()));
6703                                Process process = modelFactory.createProcess(stmt);
6704                                process.setType("Create External Table");
6705                                tableModel.addProcess(process);
6706                                Table stage = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getLocation()));
6707                                if (stage == null) {
6708                                        stage = modelManager.getTableByName(
6709                                                        DlineageUtil.getTableFullName(stmt.getStageLocation().toString().replaceFirst("@", "")));
6710                                }
6711                                if (stage == null) {
6712                                        stage = modelFactory.createTableByName(stmt.getStageLocation().toString().replaceFirst("@", ""),
6713                                                        false);
6714                                        stage.setCreateTable(false);
6715                                        stage.setStage(true);
6716                                        if (stmt.getStageLocation().getPath() != null) {
6717                                                stage.setLocation(stmt.getStageLocation().getPath().toString());
6718                                                TObjectName location = new TObjectName();
6719                                                location.setString(stmt.getStageLocation().getPath().toString());
6720                                                modelFactory.createStageLocation(stage, location);
6721                                        } else if (stmt.getRegex_pattern() != null) {
6722                                                stage.setLocation(stmt.getRegex_pattern());
6723                                                TObjectName location = new TObjectName();
6724                                                location.setString(stmt.getRegex_pattern());
6725                                                modelFactory.createStageLocation(stage, location);
6726                                        } else {
6727                                                stage.setLocation("unknownPath");
6728                                                TObjectName location = new TObjectName();
6729                                                location.setString("unknownPath");
6730                                                modelFactory.createStageLocation(stage, location);
6731                                        }
6732                                }
6733                                if (stage != null && !stage.getColumns().isEmpty()) {
6734                                        if (!tableModel.getColumns().isEmpty()) {
6735                                                for (int i = 0; i < tableModel.getColumns().size(); i++) {
6736                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6737                                                        relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
6738                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
6739                                                        relation.setProcess(process);
6740                                                }
6741                                        } else {
6742                                                TObjectName starColumn = new TObjectName();
6743                                                starColumn.setString("*");
6744                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
6745                                                tableColumn.setExpandStar(false);
6746                                                tableColumn.setShowStar(true);
6747                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6748                                                relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
6749                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6750                                                relation.setProcess(process);
6751                                        }
6752                                }
6753                        } else if (stmt.getTableOptions() != null && !stmt.getTableOptions().isEmpty()) {
6754                                for (int i = 0; i < stmt.getTableOptions().size(); i++) {
6755                                        TCreateTableOption createTableOption = stmt.getTableOptions().get(i);
6756                                        if (createTableOption.getCreateTableOptionType() != ECreateTableOption.etoBigQueryExternal)
6757                                                continue;
6758                                        List<String> uris = createTableOption.getUris();
6759                                        if (uris == null || uris.isEmpty())
6760                                                continue;
6761                                        Process process = modelFactory.createProcess(stmt);
6762                                        process.setType("Create External Table");
6763                                        tableModel.addProcess(process);
6764                                        if (tableModel.getColumns().isEmpty()) {
6765                                                TObjectName starColumn = new TObjectName();
6766                                                starColumn.setString("*");
6767                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
6768                                                tableColumn.setExpandStar(false);
6769                                                tableColumn.setShowStar(true);
6770                                        }
6771                                        for (String uri : uris) {
6772                                                Table uriFile = modelFactory.createTableByName(uri, true);
6773                                                uriFile.setPath(true);
6774                                                uriFile.setFileFormat(createTableOption.getFormat());
6775                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
6776                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6777                                                        if (stmt.getColumnList() != null) {
6778                                                                TObjectName fileUri = new TObjectName();
6779                                                                fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString());
6780                                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
6781                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
6782                                                        } else {
6783                                                                TObjectName fileUri = new TObjectName();
6784                                                                fileUri.setString("*");
6785                                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
6786                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
6787                                                        }
6788                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
6789                                                        relation.setProcess(process);
6790                                                }
6791                                                if (tableModel.getColumns().isEmpty()) {
6792                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6793                                                        TObjectName fileUri = new TObjectName();
6794                                                        fileUri.setString("*");
6795                                                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
6796                                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
6797                                                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
6798                                                                        tableModel.getRelationRows()));
6799                                                        relation.setProcess(process);
6800                                                }
6801                                        }
6802                                }
6803                        } else if (stmt.getSubQuery() == null && stmt.getTableLocation() != null) {
6804                                Process process = modelFactory.createProcess(stmt);
6805                                process.setType("Create External Table");
6806                                tableModel.addProcess(process);
6807                                Table uriFile = modelFactory.createTableByName(stmt.getTableLocation(), true);
6808                                uriFile.setPath(true);
6809                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
6810                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6811                                        if (stmt.getColumnList() != null) {
6812                                                TObjectName fileUri = new TObjectName();
6813                                                fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString());
6814                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
6815                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
6816                                        } else {
6817                                                TObjectName fileUri = new TObjectName();
6818                                                fileUri.setString("*");
6819                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
6820                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
6821                                        }
6822                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
6823                                        relation.setProcess(process);
6824                                }
6825                        }
6826
6827                        if (stmt.getTableConstraints() != null && stmt.getTableConstraints().size() > 0) {
6828                                for (int i = 0; i < stmt.getTableConstraints().size(); i++) {
6829                                        TConstraint createTableConstraint = stmt.getTableConstraints().getConstraint(i);
6830                                        TPTNodeList<TColumnWithSortOrder> keyNames = createTableConstraint.getColumnList();
6831                                        if (keyNames != null) {
6832                                                for (int k = 0; k < keyNames.size(); k++) {
6833                                                        TObjectName keyName = keyNames.getElement(k).getColumnName();
6834                                                        TObjectName referencedTableName = createTableConstraint.getReferencedObject();
6835                                                        TObjectNameList referencedTableColumns = createTableConstraint.getReferencedColumnList();
6836
6837                                                        TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
6838                                                        if (createTableConstraint.getConstraint_type() == EConstraintType.primary_key) {
6839                                                                tableConstraint.setPrimaryKey(true);
6840                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.table_index) {
6841                                                                tableConstraint.setIndexKey(true);
6842                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.unique) {
6843                                                                tableConstraint.setUnqiueKey(true);
6844                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
6845                                                                tableConstraint.setForeignKey(true);
6846                                                                Table referencedTable = modelManager
6847                                                                                .getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
6848                                                                if (referencedTable == null) {
6849                                                                        referencedTable = modelFactory.createTableByName(referencedTableName);
6850                                                                }
6851
6852                                                                if (referencedTableColumns != null) {
6853                                                                        for (int j = 0; j < referencedTableColumns.size(); j++) {
6854                                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
6855                                                                                                referencedTableColumns.getObjectName(j), false);
6856                                                                                if (tableColumn != null) {
6857                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6858                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
6859                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
6860                                                                                        relation.setEffectType(EffectType.foreign_key);
6861                                                                                        Process process = modelFactory.createProcess(stmt);
6862                                                                                        relation.setProcess(process);
6863                                                                                        if (this.option.isShowERDiagram()) {
6864                                                                                                ERRelationship erRelation = modelFactory.createERRelation();
6865                                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
6866                                                                                                erRelation
6867                                                                                                                .setTarget(new TableColumnRelationshipElement(tableConstraint));
6868                                                                                        }
6869                                                                                }
6870                                                                        }
6871                                                                }
6872                                                        }
6873                                                }
6874                                        }
6875                                }
6876                        }
6877
6878                        if (stmt.getHiveTablePartition() != null && stmt.getHiveTablePartition().getColumnDefList() != null) {
6879                                for (int i = 0; i < stmt.getHiveTablePartition().getColumnDefList().size(); i++) {
6880                                        TColumnDefinition column = stmt.getHiveTablePartition().getColumnDefList().getColumn(i);
6881                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
6882                                        appendTableColumnToSQLEnv(tableModel, column.getColumnName());
6883                                }
6884                        }
6885
6886                } else {
6887                        ErrorInfo errorInfo = new ErrorInfo();
6888                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
6889                        errorInfo.setErrorMessage("Can't get target table. CreateTableSqlStatement is " + stmt.toString());
6890                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
6891                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
6892                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
6893                                        stmt.getEndToken().columnNo + stmt.getEndToken().astext.length(),
6894                                        ModelBindingManager.getGlobalHash()));
6895                        errorInfos.add(errorInfo);
6896                }
6897        }
6898
6899        protected void flattenStructColumns(boolean hasDefinition, Table tableModel, TColumnDefinition column,
6900                        Stack<TColumnDefinition> columnPaths, int index) {
6901                columnPaths.push(column);
6902                for (int j = 0; j < column.getDatatype().getColumnDefList().size(); j++) {
6903                        TColumnDefinition columnDefinition = column.getDatatype().getColumnDefList().getColumn(j);
6904                        if (columnDefinition.getDatatype().getColumnDefList() != null) {
6905                                flattenStructColumns(hasDefinition, tableModel, columnDefinition, columnPaths, index);
6906                        } else {
6907                                TObjectName columnName = new TObjectName();
6908                                columnName.setString(getColumnName(columnPaths, columnDefinition));
6909                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName, hasDefinition);
6910                                tableColumn.setColumnIndex(index);
6911                                tableColumn.setStruct(true);
6912                                
6913                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
6914                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
6915                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
6916                                        crudRelationship.setEffectType(EffectType.create_table);
6917                                }
6918                                
6919                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6920                        }
6921                }
6922                columnPaths.pop();
6923        }
6924
6925        private String getColumnName(Stack<TColumnDefinition> columnPaths, TColumnDefinition column) {
6926                StringBuilder buffer = new StringBuilder();
6927                Iterator<TColumnDefinition> iter = columnPaths.iterator();
6928                while(iter.hasNext()) {
6929                        buffer.append(iter.next().getColumnName().getColumnNameOnly()).append(".");
6930                }
6931                buffer.append(column.getColumnName().getColumnNameOnly());
6932                return buffer.toString();
6933        }
6934
6935        private void appendTableColumnToSQLEnv(Table tableModel, TableColumn tableColumn) {
6936                //tableModel如果非determined,请不要添加到sqlenv里
6937                if (sqlenv != null && tableColumn!=null) {
6938                        TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true);
6939                        if (schema != null) {
6940                                TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
6941                                if (tableColumn.hasStarLinkColumn()) {
6942                                        for (String column : tableColumn.getStarLinkColumnNames()) {
6943                                                tempTable.addColumn(DlineageUtil.getColumnNameOnly(column));
6944                                        }
6945                                } else {
6946                                        tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getName()));
6947                                }
6948                        }
6949                }
6950        }
6951
6952        private void appendTableColumnToSQLEnv(Table tableModel, TObjectName tableColumn) {
6953                if (sqlenv != null) {
6954                        TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true);
6955                        if (schema != null) {
6956                                TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
6957                                tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getColumnNameOnly()));
6958                        }
6959                }
6960        }
6961
6962        private void analyzeCreateStageStmt(TCreateStageStmt stmt) {
6963                TObjectName stageName = stmt.getStageName();
6964
6965                if (stageName != null) {
6966
6967                        Table tableModel = modelFactory.createStage(stageName);
6968                        tableModel.setCreateTable(true);
6969                        tableModel.setStage(true);
6970                        tableModel.setLocation(stmt.getExternalStageURL());
6971
6972                        Process process = modelFactory.createProcess(stmt);
6973                        tableModel.addProcess(process);
6974
6975                        TableColumn locationColumn = null;
6976                        if (stmt.getExternalStageURL() != null) {
6977                                TObjectName location = new TObjectName();
6978                                location.setString(stmt.getExternalStageURL());
6979                                locationColumn = modelFactory.createStageLocation(tableModel, location);
6980
6981                                Table pathModel = modelFactory.createTableByName(stmt.getExternalStageURL(), true);
6982                                pathModel.setPath(true);
6983                                pathModel.setCreateTable(true);
6984                                TObjectName fileUri = new TObjectName();
6985                                fileUri.setString(stmt.getExternalStageURL());
6986                                TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri);
6987
6988                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6989                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
6990                                relation.setTarget(new TableColumnRelationshipElement(locationColumn));
6991                                relation.setProcess(process);
6992
6993                        } else {
6994                                for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) {
6995                                        if (temp instanceof TPutStmt) {
6996                                                TPutStmt put = (TPutStmt) temp;
6997                                                TStageLocation stageLocation = put.getStageLocation();
6998                                                if (stageLocation != null && stageLocation.getStageName() != null) {
6999                                                        Table stage = modelManager.getTableByName(
7000                                                                        DlineageUtil.getTableFullName(stageLocation.getStageName().toString()));
7001                                                        if (stage == tableModel) {
7002                                                                TObjectName location = new TObjectName();
7003                                                                if (!SQLUtil.isEmpty(put.getFileName())) {
7004                                                                        location.setString(put.getFileName());
7005                                                                        locationColumn = modelFactory.createStageLocation(tableModel, location);
7006                                                                }
7007                                                                break;
7008                                                        }
7009                                                }
7010                                        }
7011                                }
7012                        }
7013
7014                        String fileFormat = stmt.getFileFormatName();
7015                        if (fileFormat != null) {
7016                                for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) {
7017                                        if (temp instanceof TCreateFileFormatStmt) {
7018                                                TCreateFileFormatStmt fileFormatStmt = (TCreateFileFormatStmt) temp;
7019                                                if (fileFormatStmt.getFileFormatName() != null
7020                                                                && fileFormatStmt.getFileFormatName().toString().equalsIgnoreCase(fileFormat)) {
7021                                                        tableModel.setFileType(fileFormatStmt.getTypeName());
7022                                                        break;
7023                                                }
7024                                        }
7025                                }
7026                        }
7027
7028                        String procedureParent = getProcedureParentName(stmt);
7029                        if (procedureParent != null) {
7030                                tableModel.setParent(procedureParent);
7031                        }
7032
7033                        if (locationColumn != null) {
7034                                List<Table> tables = modelManager.getTablesByName();
7035                                if (tables != null) {
7036                                        for (Table referTable : tables) {
7037                                                if (referTable.getLocation() != null && referTable.getLocation()
7038                                                                .equals(DlineageUtil.getIdentifierNormalTableName(tableModel.getName()))) {
7039                                                        for (int i = 0; i < referTable.getColumns().size(); i++) {
7040                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7041                                                                relation.addSource(new TableColumnRelationshipElement(locationColumn));
7042                                                                relation.setTarget(new TableColumnRelationshipElement(referTable.getColumns().get(i)));
7043                                                        }
7044                                                }
7045                                        }
7046                                }
7047                        }
7048                } else {
7049                        ErrorInfo errorInfo = new ErrorInfo();
7050                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7051                        errorInfo.setErrorMessage("Can't get target table. CreateStageStmt is " + stmt.toString());
7052                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7053                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7054                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7055                                        stmt.getEndToken().columnNo + stmt.getEndToken().astext.length(),
7056                                        ModelBindingManager.getGlobalHash()));
7057                        errorInfo.fillInfo(this);
7058                        errorInfos.add(errorInfo);
7059                }
7060        }
7061
7062        private void analyzeCreateExternalDataSourceStmt(TCreateExternalDataSourceStmt stmt) {
7063                TObjectName dataSourceName = stmt.getDataSourceName();
7064                String locationUrl = stmt.getOption("LOCATION");
7065                if (dataSourceName != null && locationUrl != null) {
7066                        Table tableModel = modelFactory.createDataSource(dataSourceName);
7067                        tableModel.setCreateTable(true);
7068                        tableModel.setDataSource(true);
7069                        tableModel.setLocation(locationUrl);
7070
7071                        Process process = modelFactory.createProcess(stmt);
7072                        tableModel.addProcess(process);
7073
7074                        TObjectName location = new TObjectName();
7075                        location.setString(locationUrl);
7076                        modelFactory.createTableColumn(tableModel, location, true);
7077
7078                        String procedureParent = getProcedureParentName(stmt);
7079                        if (procedureParent != null) {
7080                                tableModel.setParent(procedureParent);
7081                        }
7082                } else {
7083                        ErrorInfo errorInfo = new ErrorInfo();
7084                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7085                        errorInfo.setErrorMessage("Can't get target table. CreateExternalDataSourceStmt is " + stmt.toString());
7086                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7087                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7088                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7089                                        stmt.getEndToken().columnNo + stmt.getEndToken().astext.length(),
7090                                        ModelBindingManager.getGlobalHash()));
7091                        errorInfo.fillInfo(this);
7092                        errorInfos.add(errorInfo);
7093                }
7094        }
7095
7096        private void analyzeCreateStreamStmt(TCreateStreamStmt stmt) {
7097                TObjectName streamName = stmt.getStreamName();
7098
7099                if (streamName != null) {
7100                        Table tableModel = modelFactory.createTableByName(stmt.getTableName());
7101                        tableModel.setCreateTable(true);
7102
7103                        Table streamModel = modelFactory.createStream(streamName);
7104                        streamModel.setCreateTable(true);
7105                        streamModel.setStream(true);
7106
7107                        Process process = modelFactory.createProcess(stmt);
7108                        tableModel.addProcess(process);
7109
7110                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7111                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(streamModel.getRelationRows()));
7112                        relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
7113                        relation.setProcess(process);
7114                }
7115        }
7116
7117        private String getProcedureParentName(TCustomSqlStatement stmt) {
7118                if (stmt instanceof TStoredProcedureSqlStatement) {
7119                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
7120                                return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
7121                        }
7122                }
7123
7124                stmt = stmt.getParentStmt();
7125                if (stmt == null)
7126                        return null;
7127
7128        if (stmt instanceof TCommonBlock) {
7129                        if(((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) {
7130                                stmt = (TStoredProcedureSqlStatement)((TCommonBlock) stmt).getBlockBody().getParentObjectName();
7131                        }
7132                }
7133
7134                if (stmt instanceof TStoredProcedureSqlStatement) {
7135                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
7136                                return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
7137                        }
7138                }
7139                if (stmt instanceof TTeradataCreateProcedure) {
7140                        if (((TTeradataCreateProcedure) stmt).getProcedureName() != null) {
7141                                return ((TTeradataCreateProcedure) stmt).getProcedureName().toString();
7142                        }
7143                }
7144
7145                return getProcedureParentName(stmt);
7146        }
7147
7148        private TStoredProcedureSqlStatement getProcedureParent(TCustomSqlStatement stmt) {
7149                if (stmt instanceof TStoredProcedureSqlStatement) {
7150                        return (TStoredProcedureSqlStatement) stmt;
7151                }
7152
7153                stmt = stmt.getParentStmt();
7154                if (stmt == null)
7155                        return null;
7156
7157                if (stmt instanceof TCommonBlock) {
7158                        if (((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) {
7159                                stmt = (TStoredProcedureSqlStatement) ((TCommonBlock) stmt).getBlockBody().getParentObjectName();
7160                        }
7161                }
7162
7163                if (stmt instanceof TStoredProcedureSqlStatement) {
7164                        return ((TStoredProcedureSqlStatement) stmt);
7165                }
7166                if (stmt instanceof TTeradataCreateProcedure) {
7167                        return ((TTeradataCreateProcedure) stmt);
7168                }
7169
7170                return getProcedureParent(stmt);
7171        }
7172
7173        private void analyzeMergeStmt(TMergeSqlStatement stmt) {
7174                Object tableModel;
7175                Process process;
7176                if (stmt.getUsingTable() != null) {
7177                        TTable table = stmt.getTargetTable();
7178                        if(table.getSubquery()!=null) {
7179                                tableModel = modelFactory.createQueryTable(table);
7180                                analyzeSelectStmt(table.getSubquery());
7181                                process = modelFactory.createProcess(stmt);
7182                        }
7183                        else {
7184                                tableModel = modelFactory.createTable(table);
7185                                process = modelFactory.createProcess(stmt);
7186                                ((Table)tableModel).addProcess(process);
7187                        }
7188                        
7189                        for(TTable item: stmt.tables) {
7190                                if(item.getSubquery()!=null) {
7191                                        continue;
7192                                }
7193                                Table tableItemModel = modelFactory.createTable(item);                          
7194                                if (tableItemModel.getColumns() == null || tableItemModel.getColumns().isEmpty()) {
7195                                        tableItemModel.addColumnsFromSQLEnv();
7196                                }
7197                        }
7198
7199                        if (stmt.getUsingTable().getSubquery() != null) {
7200                                QueryTable queryTable = modelFactory.createQueryTable(stmt.getUsingTable());
7201                                analyzeSelectStmt(stmt.getUsingTable().getSubquery());
7202
7203                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getUsingTable().getSubquery());
7204                                
7205                                if (queryTable != null && resultSetModel != null && queryTable != resultSetModel) {
7206                                        if (queryTable.getColumns().size() == resultSetModel.getColumns().size()) {
7207                                                for (int i = 0; i < queryTable.getColumns().size(); i++) {
7208                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7209                                                        relation.setEffectType(EffectType.select);
7210                                                        relation.setTarget(new ResultColumnRelationshipElement(queryTable.getColumns().get(i)));
7211                                                        relation.addSource(new ResultColumnRelationshipElement(resultSetModel.getColumns().get(i)));
7212                                                        relation.setProcess(process);
7213                                                }
7214                                        }
7215                                }
7216                                
7217                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
7218                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
7219                                        impactRelation.setEffectType(EffectType.merge);
7220                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
7221                                                        resultSetModel.getRelationRows()));
7222                                        if (tableModel instanceof Table) {
7223                                                impactRelation.setTarget(
7224                                                                new RelationRowsRelationshipElement<TableRelationRows>(((Table)tableModel).getRelationRows()));
7225                                        }
7226                                        else {
7227                                                impactRelation.setTarget(
7228                                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)tableModel).getRelationRows()));
7229                                        }
7230                                }
7231                        } else {
7232                                if (stmt.getUsingTable().getAliasClause() != null && stmt.getUsingTable().getAliasClause().getColumns() != null && stmt.getUsingTable().getValueClause().getRows()!=null) {
7233                                        Table usingTable = modelFactory.createTableFromCreateDDL(stmt.getUsingTable(), false, stmt.getUsingTable().getAliasName() + stmt.getUsingTable().getTableName());
7234                                        usingTable.setCreateTable(true);
7235                                        usingTable.setSubType(SubType.function);
7236                                        for (int z=0;z<stmt.getUsingTable().getAliasClause().getColumns().size();z++) {
7237                                                TObjectName columnName = stmt.getUsingTable().getAliasClause().getColumns().getObjectName(z);
7238                                                TableColumn tableColumn = modelFactory.createTableColumn(usingTable, columnName, true);
7239                                                TResultColumn resultColumn = stmt.getUsingTable().getValueClause().getRows().get(0).getResultColumn(z);
7240                                                modelManager.bindModel(resultColumn, tableColumn);
7241                                                analyzeResultColumnExpressionRelation(tableColumn, resultColumn.getExpr());                                             }
7242                                }
7243                                else {
7244                                        modelFactory.createTable(stmt.getUsingTable());
7245                                }
7246                        }
7247                
7248
7249                        if (stmt.getWhenClauses() != null && stmt.getWhenClauses().size() > 0) {
7250                                for (int i = 0; i < stmt.getWhenClauses().size(); i++) {
7251                                        TMergeWhenClause clause = stmt.getWhenClauses().getElement(i);
7252                                        if (clause.getCondition() != null) {
7253                                                analyzeFilterCondition(null, clause.getCondition(), null, null, EffectType.merge_when);
7254                                        }
7255                                        if (clause.getUpdateClause() != null) {
7256                                                TResultColumnList columns = clause.getUpdateClause().getUpdateColumnList();
7257                                                if (columns == null || columns.size() == 0)
7258                                                        continue;
7259
7260                                                ResultSet resultSet = modelFactory.createResultSet(clause.getUpdateClause(), false);
7261                                                createPseudoImpactRelation(stmt, resultSet, EffectType.merge_update);
7262
7263                                                for (int j = 0; j < columns.size(); j++) {
7264                                                        TResultColumn resultColumn = columns.getResultColumn(j);
7265                                                        if (resultColumn.getExpr().getLeftOperand()
7266                                                                        .getExpressionType() == EExpressionType.simple_object_name_t) {
7267                                                                TObjectName columnObject = resultColumn.getExpr().getLeftOperand().getObjectOperand();
7268
7269                                                                if (columnObject.getDbObjectType() == EDbObjectType.variable) {
7270                                                                        continue;
7271                                                                }
7272
7273                                                                if (columnObject.getColumnNameOnly().startsWith("@")
7274                                                                                && (option.getVendor() == EDbVendor.dbvmssql
7275                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
7276                                                                        continue;
7277                                                                }
7278
7279                                                                if (columnObject.getColumnNameOnly().startsWith(":")
7280                                                                                && (option.getVendor() == EDbVendor.dbvhana
7281                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
7282                                                                        continue;
7283                                                                }
7284
7285                                                                ResultColumn updateColumn = modelFactory.createMergeResultColumn(resultSet,
7286                                                                                columnObject);
7287
7288                                                                TExpression valueExpression = resultColumn.getExpr().getRightOperand();
7289                                                                if (valueExpression == null)
7290                                                                        continue;
7291
7292                                                                columnsInExpr visitor = new columnsInExpr();
7293                                                                valueExpression.inOrderTraverse(visitor);
7294                                                                List<TObjectName> objectNames = visitor.getObjectNames();
7295                                                                List<TParseTreeNode> functions = visitor.getFunctions();
7296
7297                                                                if (functions != null && !functions.isEmpty()) {
7298                                                                        analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.merge_update);
7299                                                                }
7300
7301                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
7302                                                                if (subquerys != null && !subquerys.isEmpty()) {
7303                                                                        analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.merge_update);
7304                                                                }
7305
7306                                                                analyzeDataFlowRelation(updateColumn, objectNames, EffectType.merge_update, functions);
7307
7308                                                                List<TParseTreeNode> constants = visitor.getConstants();
7309                                                                analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.merge_update,
7310                                                                                functions);
7311
7312                                                                if (tableModel instanceof Table) {
7313                                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel, columnObject,
7314                                                                                        false);
7315
7316                                                                        if (tableColumn != null) {
7317                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7318                                                                                relation.setEffectType(EffectType.merge_update);
7319                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7320                                                                                relation.addSource(new ResultColumnRelationshipElement(updateColumn));
7321                                                                                relation.setProcess(process);
7322                                                                        }
7323                                                                }
7324                                                                else {
7325                                                                        TTable targetTable = stmt.getTargetTable().getSubquery().getTables().getTable(0);
7326                                                                        if (targetTable != null && modelManager.getModel(targetTable) instanceof Table) {
7327                                                                                Table targetTableModel = (Table) modelManager.getModel(targetTable);
7328                                                                                TableColumn tableColumn = modelFactory
7329                                                                                                .createTableColumn((Table) targetTableModel, columnObject, false);
7330                                                                                if (tableColumn != null) {
7331                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7332                                                                                        relation.setEffectType(EffectType.merge_update);
7333                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7334                                                                                        relation.addSource(new ResultColumnRelationshipElement(updateColumn));
7335                                                                                        relation.setProcess(process);
7336                                                                                }
7337                                                                        }
7338                                                                }
7339                                                        }
7340                                                }
7341                                        }
7342                                        if (clause.getInsertClause() != null && tableModel instanceof Table) {
7343                                                TExpression insertValue = clause.getInsertClause().getInsertValue();
7344                                                if (insertValue != null
7345                                                                && insertValue.getExpressionType() == EExpressionType.objectConstruct_t) {
7346                                                        ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false);
7347
7348                                                        createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert);
7349
7350                                                        TObjectConstruct objectConstruct = insertValue.getObjectConstruct();
7351                                                        for (int z = 0; z < objectConstruct.getPairs().size(); z++) {
7352                                                                TPair pair = objectConstruct.getPairs().getElement(z);
7353
7354                                                                if (pair.getKeyName().getExpressionType() == EExpressionType.simple_constant_t) {
7355                                                                        TObjectName columnObject = new TObjectName();
7356                                                                        TConstant constant = pair.getKeyName().getConstantOperand();
7357                                                                        TSourceToken newSt = new TSourceToken(
7358                                                                                        constant.getValueToken().getTextWithoutQuoted());
7359                                                                        columnObject.setPartToken(newSt);
7360                                                                        columnObject.setSourceTable(stmt.getTargetTable());
7361                                                                        columnObject.setStartToken(constant.getStartToken());
7362                                                                        columnObject.setEndToken(constant.getEndToken());
7363
7364                                                                        ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet,
7365                                                                                        columnObject);
7366
7367                                                                        TExpression valueExpression = pair.getKeyValue();
7368                                                                        if (valueExpression == null)
7369                                                                                continue;
7370
7371                                                                        columnsInExpr visitor = new columnsInExpr();
7372                                                                        valueExpression.inOrderTraverse(visitor);
7373                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
7374                                                                        List<TParseTreeNode> functions = visitor.getFunctions();
7375
7376                                                                        if (functions != null && !functions.isEmpty()) {
7377                                                                                analyzeFunctionDataFlowRelation(insertColumn, functions,
7378                                                                                                EffectType.merge_insert);
7379                                                                        }
7380
7381                                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
7382                                                                        if (subquerys != null && !subquerys.isEmpty()) {
7383                                                                                analyzeSubqueryDataFlowRelation(insertColumn, subquerys,
7384                                                                                                EffectType.merge_insert);
7385                                                                        }
7386
7387                                                                        analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert,
7388                                                                                        functions);
7389
7390                                                                        List<TParseTreeNode> constants = visitor.getConstants();
7391                                                                        analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert,
7392                                                                                        functions);
7393
7394                                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel,
7395                                                                                        columnObject, false);
7396
7397                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7398                                                                        relation.setEffectType(EffectType.merge_insert);
7399                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7400                                                                        relation.addSource(new ResultColumnRelationshipElement(insertColumn));
7401                                                                        relation.setProcess(process);
7402                                                                }
7403                                                        }
7404                                                } else {
7405                                                        TObjectNameList columns = clause.getInsertClause().getColumnList();
7406                                                        TResultColumnList values = clause.getInsertClause().getValuelist();
7407                                                        if (values == null || values.size() == 0) {
7408                                                                if (clause.getInsertClause().toString().toLowerCase().indexOf("row") != -1) {
7409                                                                        if (stmt.getUsingTable().getSubquery() != null) {
7410                                                                                ResultSet sourceResultSet = modelFactory.createQueryTable(stmt.getUsingTable());
7411                                                                                TObjectName targetStarColumn = new TObjectName();
7412                                                                                targetStarColumn.setString("*");
7413                                                                                TableColumn targetTableColumn = modelFactory.createTableColumn((Table)tableModel,
7414                                                                                                targetStarColumn, true);
7415                                                                                if (sourceResultSet.getColumns() == null
7416                                                                                                || sourceResultSet.getColumns().isEmpty()) {
7417                                                                                        TObjectName sourceStarColumn = new TObjectName();
7418                                                                                        sourceStarColumn.setString("*");
7419                                                                                        modelFactory.createResultColumn(sourceResultSet, sourceStarColumn);
7420                                                                                }
7421                                                                                for (ResultColumn sourceColumn : sourceResultSet.getColumns()) {
7422                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7423                                                                                        relation.setEffectType(EffectType.merge_insert);
7424                                                                                        relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
7425                                                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
7426                                                                                        relation.setProcess(process);
7427                                                                                }
7428                                                                        } else {
7429                                                                                Table sourceTable = modelFactory.createTable(stmt.getUsingTable());
7430                                                                                TObjectName sourceStarColumn = new TObjectName();
7431                                                                                sourceStarColumn.setString("*");
7432                                                                                TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable,
7433                                                                                                sourceStarColumn, true);
7434                                                                                TObjectName targetStarColumn = new TObjectName();
7435                                                                                targetStarColumn.setString("*");
7436                                                                                TableColumn targetTableColumn = modelFactory.createTableColumn(((Table)tableModel),
7437                                                                                                targetStarColumn, true);
7438                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7439                                                                                relation.setEffectType(EffectType.merge_insert);
7440                                                                                relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
7441                                                                                relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
7442                                                                                relation.setProcess(process);
7443                                                                        }
7444
7445                                                                }
7446                                                                continue;
7447                                                        }
7448
7449                                                        List<TObjectName> tableColumns = new ArrayList<TObjectName>();
7450                                                        if (columns == null || columns.size() == 0) {
7451//                                                              if (!((Table)tableModel).getColumns().isEmpty()) {
7452//                                                                      for (int j = 0; j < ((Table)tableModel).getColumns().size(); j++) {
7453//                                                                              if (((Table)tableModel).getColumns().get(j).getColumnObject() == null) {
7454//                                                                                      continue;
7455//                                                                              }
7456//                                                                              tableColumns.add(((Table)tableModel).getColumns().get(j).getColumnObject());
7457//                                                                      }
7458//                                                              } else {
7459                                                                        for (int j = 0; j < values.size(); j++) {
7460                                                                                TResultColumn column = values.getResultColumn(j);
7461                                                                                if (column.getAliasClause() != null) {
7462                                                                                        tableColumns.add(column.getAliasClause().getAliasName());
7463                                                                                } else if (column.getFieldAttr() != null) {
7464                                                                                        tableColumns.add(column.getFieldAttr());
7465                                                                                } else {
7466                                                                                        TObjectName columnName = new TObjectName();
7467                                                                                        columnName.setString(column.toString());
7468                                                                                        tableColumns.add(columnName);
7469                                                                                }
7470//                                                                      }
7471                                                                }
7472                                                        } else {
7473                                                                for (int j = 0; j < columns.size(); j++) {
7474                                                                        tableColumns.add(columns.getObjectName(j));
7475                                                                }
7476                                                        }
7477
7478                                                        ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false);
7479
7480                                                        createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert);
7481
7482                                                        for (int j = 0; j < tableColumns.size() && j < values.size(); j++) {
7483                                                                TObjectName columnObject = tableColumns.get(j);
7484
7485                                                                ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet,
7486                                                                                columnObject);
7487
7488                                                                TExpression valueExpression = values.getResultColumn(j).getExpr();
7489                                                                if (valueExpression == null)
7490                                                                        continue;
7491
7492                                                                columnsInExpr visitor = new columnsInExpr();
7493                                                                valueExpression.inOrderTraverse(visitor);
7494                                                                List<TObjectName> objectNames = visitor.getObjectNames();
7495                                                                List<TParseTreeNode> functions = visitor.getFunctions();
7496
7497                                                                if (functions != null && !functions.isEmpty()) {
7498                                                                        analyzeFunctionDataFlowRelation(insertColumn, functions, EffectType.merge_insert);
7499                                                                }
7500
7501                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
7502                                                                if (subquerys != null && !subquerys.isEmpty()) {
7503                                                                        analyzeSubqueryDataFlowRelation(insertColumn, subquerys, EffectType.merge_insert);
7504                                                                }
7505
7506                                                                analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert, functions);
7507
7508                                                                List<TParseTreeNode> constants = visitor.getConstants();
7509                                                                analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert,
7510                                                                                functions);
7511
7512                                                                TableColumn tableColumn = modelFactory.createTableColumn(((Table)tableModel), columnObject,
7513                                                                                false);
7514                                                                if(tableColumn == null) {
7515                                                                        if (((Table) tableModel).isCreateTable()) {
7516                                                                                tableColumn = ((Table) tableModel).getColumns().get(j);
7517                                                                        }
7518                                                                        else {
7519                                                                                continue;
7520                                                                        }
7521                                                                }
7522
7523                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7524                                                                relation.setEffectType(EffectType.merge_insert);
7525                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7526                                                                relation.addSource(new ResultColumnRelationshipElement(insertColumn));
7527                                                                relation.setProcess(process);
7528                                                        }
7529                                                }
7530                                        }
7531                                }
7532
7533                        }
7534
7535                        if (stmt.getCondition() != null) {
7536                                analyzeFilterCondition(null, stmt.getCondition(), null, JoinClauseType.on, EffectType.merge);
7537                        }
7538                }
7539        }
7540
7541        private List<TableColumn> bindInsertTableColumn(Table tableModel, TInsertIntoValue value, List<TObjectName> keyMap,
7542                        List<TResultColumn> valueMap) {
7543                List<TableColumn> tableColumns = new ArrayList<TableColumn>();
7544                if (value.getColumnList() != null) {
7545                        for (int z = 0; z < value.getColumnList().size(); z++) {
7546                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
7547                                                value.getColumnList().getObjectName(z));
7548                                tableColumns.add(tableColumn);
7549                                keyMap.add(tableColumn.getColumnObject());
7550                        }
7551                }
7552
7553                if (value.getTargetList() != null) {
7554                        for (int z = 0; z < value.getTargetList().size(); z++) {
7555                                TMultiTarget target = value.getTargetList().getMultiTarget(z);
7556                                TResultColumnList columns = target.getColumnList();
7557                                for (int i = 0; i < columns.size(); i++) {
7558                                        if (value.getColumnList() == null) {
7559                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
7560                                                                columns.getResultColumn(i).getFieldAttr());
7561                                                tableColumns.add(tableColumn);
7562                                        }
7563                                        valueMap.add(columns.getResultColumn(i));
7564                                }
7565                        }
7566                }
7567
7568                return tableColumns;
7569        }
7570
7571        private TableColumn matchColumn(List<TableColumn> tableColumns, TableColumn targetColumn) {
7572                String columnName = targetColumn.getName();
7573                if (tableColumns == null) {
7574                        return null;
7575                }
7576                for (int i = 0; i < tableColumns.size(); i++) {
7577                        TableColumn column = tableColumns.get(i);
7578                        if (column.getColumnObject() == null) {
7579                                continue;
7580                        }
7581                        if(column.isStruct() && targetColumn.isStruct()) {
7582                                List<String> names = SQLUtil.parseNames(column.getName());
7583                                List<String> targetNames = SQLUtil
7584                                                .parseNames(targetColumn.getName());
7585                                if (!getColumnName(targetNames.get(0))
7586                                                .equals(getColumnName(names.get(0)))) {
7587                                        continue;
7588                                }
7589                        }
7590                        if (getColumnName(column.getColumnObject().toString()).equals(getColumnName(columnName))) {
7591                                return column;
7592                        }
7593                }
7594                return null;
7595        }
7596        
7597        private TableColumn matchColumn(List<TableColumn> tableColumns, TObjectName columnName) {
7598                if (tableColumns == null) {
7599                        return null;
7600                }
7601                for (int i = 0; i < tableColumns.size(); i++) {
7602                        TableColumn column = tableColumns.get(i);
7603                        if (column.getColumnObject() == null) {
7604                                continue;
7605                        }
7606                        if (DlineageUtil.getIdentifierNormalColumnName(column.getColumnObject().toString()).equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName.toString())))
7607                                return column;
7608                }
7609                return null;
7610        }
7611
7612        private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, ResultColumn resultColumn) {
7613                if (resultColumns == null) {
7614                        return null;
7615                }
7616
7617                TObjectName columnName = getObjectName(resultColumn);
7618                if (columnName == null) {
7619                        return null;
7620                }
7621
7622                for (int i = 0; i < resultColumns.size(); i++) {
7623                        ResultColumn column = resultColumns.get(i);
7624                        if (column.getAlias() != null
7625                                        && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName)))
7626                                return column;
7627                        if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName)))
7628                                return column;
7629                        if (column.getName() != null && column.getName().endsWith("*")) {
7630                                if ("*".equals(column.getColumnObject().toString())) {
7631                                        return column;
7632                                } else {
7633                                        TObjectName columnObjectName = getObjectName(column);
7634                                        if (columnObjectName.getTableString() != null
7635                                                        && columnObjectName.getTableString().equals(getResultSetAlias(resultColumn))) {
7636                                                return column;
7637                                        }
7638                                }
7639                        }
7640                }
7641                return null;
7642        }
7643
7644        private String getResultSetAlias(ResultColumn resultColumn) {
7645                ResultSet resultSet = resultColumn.getResultSet();
7646                if (resultSet instanceof QueryTable) {
7647                        return ((QueryTable) resultSet).getAlias();
7648                }
7649                return null;
7650        }
7651
7652        private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, TObjectName columnName) {
7653                if (resultColumns == null) {
7654                        return null;
7655                }
7656                for (int i = 0; i < resultColumns.size(); i++) {
7657                        ResultColumn column = resultColumns.get(i);
7658                        if (column.getAlias() != null
7659                                        && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName)))
7660                                return column;
7661                        if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName)))
7662                                return column;
7663                        if (column.getName() != null && column.getName().endsWith("*")) {
7664                                if ("*".equals(column.getColumnObject().toString())) {
7665                                        return column;
7666                                } else {
7667                                        TObjectName columnObjectName = getObjectName(column);
7668                                        if (columnObjectName.getTableString() != null
7669                                                        && columnObjectName.getTableString().equals(columnName.getTableString())) {
7670                                                return column;
7671                                        }
7672                                }
7673                        }
7674                }
7675                return null;
7676        }
7677
7678        private void analyzeInsertStmt(TInsertSqlStatement stmt) {
7679                Map<Table, List<TObjectName>> insertTableKeyMap = new LinkedHashMap<Table, List<TObjectName>>();
7680                Map<Table, List<TResultColumn>> insertTableValueMap = new LinkedHashMap<Table, List<TResultColumn>>();
7681                Map<String, List<TableColumn>> tableColumnMap = new LinkedHashMap<String, List<TableColumn>>();
7682                List<Table> inserTables = new ArrayList<Table>();
7683                List<TExpression> expressions = new ArrayList<TExpression>();
7684                boolean hasInsertColumns = false;
7685                
7686                EffectType effectType = EffectType.insert;
7687                if(stmt.getInsertToken()!=null && stmt.getInsertToken().toString().toLowerCase().startsWith("replace")) {
7688                        effectType = EffectType.replace;
7689                }
7690                
7691                if (stmt.getInsertConditions() != null && stmt.getInsertConditions().size() > 0) {
7692                        for (int i = 0; i < stmt.getInsertConditions().size(); i++) {
7693                                TInsertCondition condition = stmt.getInsertConditions().getElement(i);
7694                                if (condition.getCondition() != null) {
7695                                        expressions.add(condition.getCondition());
7696                                }
7697                                for (int j = 0; j < condition.getInsertIntoValues().size(); j++) {
7698                                        TInsertIntoValue value = condition.getInsertIntoValues().getElement(j);
7699                                        TTable table = value.getTable();
7700                                        Table tableModel = modelFactory.createTable(table);
7701
7702                                        inserTables.add(tableModel);
7703                                        List<TObjectName> keyMap = new ArrayList<TObjectName>();
7704                                        List<TResultColumn> valueMap = new ArrayList<TResultColumn>();
7705                                        insertTableKeyMap.put(tableModel, keyMap);
7706                                        insertTableValueMap.put(tableModel, valueMap);
7707
7708                                        List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap);
7709                                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null
7710                                                        && !tableColumns.isEmpty()) {
7711                                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()),
7712                                                                tableColumns);
7713                                        }
7714
7715                                        // if (stmt.getSubQuery() != null)
7716                                        {
7717                                                Process process = modelFactory.createProcess(stmt);
7718                                                tableModel.addProcess(process);
7719                                        }
7720                                }
7721                        }
7722                        hasInsertColumns = true;
7723                } else if (stmt.getInsertIntoValues() != null && stmt.getInsertIntoValues().size() > 0) {
7724                        for (int i = 0; i < stmt.getInsertIntoValues().size(); i++) {
7725                                TInsertIntoValue value = stmt.getInsertIntoValues().getElement(i);
7726                                TTable table = value.getTable();
7727                                Table tableModel = modelFactory.createTable(table);
7728
7729                                inserTables.add(tableModel);
7730                                List<TObjectName> keyMap = new ArrayList<TObjectName>();
7731                                List<TResultColumn> valueMap = new ArrayList<TResultColumn>();
7732                                insertTableKeyMap.put(tableModel, keyMap);
7733                                insertTableValueMap.put(tableModel, valueMap);
7734
7735                                List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap);
7736                                if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
7737                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
7738                                }
7739
7740                                // if (stmt.getSubQuery() != null)
7741                                {
7742                                        Process process = modelFactory.createProcess(stmt);
7743                                        tableModel.addProcess(process);
7744                                }
7745                        }
7746                        hasInsertColumns = true;
7747                } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
7748                        TTable table = stmt.getTargetTable();
7749                        Table tableModel = modelFactory.createTable(table);
7750
7751                        inserTables.add(tableModel);
7752                        List<TObjectName> keyMap = new ArrayList<TObjectName>();
7753                        insertTableKeyMap.put(tableModel, keyMap);
7754                        List<TableColumn> tableColumns = new ArrayList<TableColumn>();
7755                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
7756                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
7757                                                stmt.getColumnList().getObjectName(i));
7758                                tableColumns.add(tableColumn);
7759                        }
7760                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
7761                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
7762                        }
7763
7764                        // if (stmt.getSubQuery() != null)
7765                        {
7766                                Process process = modelFactory.createProcess(stmt);
7767                                tableModel.addProcess(process);
7768                        }
7769                        hasInsertColumns = true;
7770                } else {
7771                        TTable table = stmt.getTargetTable();
7772                        Table tableModel;
7773                        if (table != null) {
7774                                tableModel = modelFactory.createTable(table);
7775                                // if (stmt.getSubQuery() != null)
7776                                {
7777                                        Process process = modelFactory.createProcess(stmt);
7778                                        tableModel.addProcess(process);
7779                                }
7780                                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
7781                                        tableModel.addColumnsFromSQLEnv();
7782                                }
7783                        } else if (stmt.getDirectoryName() != null) {
7784                                tableModel = modelFactory.createTableByName(stmt.getDirectoryName(), true);
7785                                tableModel.setPath(true);
7786                                tableModel.setCreateTable(true);
7787                                TObjectName fileUri = new TObjectName();
7788                                fileUri.setString("uri=" + stmt.getDirectoryName());
7789                                TableColumn tableColumn = modelFactory.createFileUri(tableModel, fileUri);
7790                                // if (stmt.getSubQuery() != null)
7791                                {
7792                                        Process process = modelFactory.createProcess(stmt);
7793                                        tableModel.addProcess(process);
7794                                }
7795                        } else {
7796                                ErrorInfo errorInfo = new ErrorInfo();
7797                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7798                                errorInfo.setErrorMessage("Can't get target table. InsertSqlStatement is " + stmt.toString());
7799                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7800                                                stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7801                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7802                                                stmt.getEndToken().columnNo + stmt.getEndToken().astext.length(),
7803                                                ModelBindingManager.getGlobalHash()));
7804                                errorInfo.fillInfo(this);
7805                                errorInfos.add(errorInfo);
7806                                return;
7807                        }
7808                        inserTables.add(tableModel);
7809                        if (table != null
7810                                        && tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null) {
7811                                if (tableModel.getColumns() != null && !tableModel.getColumns().isEmpty()) {
7812                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()),
7813                                                        tableModel.getColumns());
7814                                } else {
7815                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), null);
7816                                }
7817                        }
7818                }
7819
7820                if (stmt.getSubQuery() != null) {
7821                        analyzeSelectStmt(stmt.getSubQuery());
7822                }
7823
7824                Iterator<Table> tableIter = inserTables.iterator();
7825                while (tableIter.hasNext()) {
7826                        Table tableModel = tableIter.next();
7827                        List<TableColumn> tableColumns = tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()));
7828                        List<TObjectName> keyMap = insertTableKeyMap.get(tableModel);
7829                        List<TResultColumn> valueMap = insertTableValueMap.get(tableModel);
7830                        boolean initColumn = (hasInsertColumns && tableColumns != null && !containStarColumn(tableColumns));
7831
7832                        if (stmt.getSubQuery() != null) {
7833
7834                                List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>();
7835                                if (stmt.getSubQuery().getResultColumnList() != null || stmt.getSubQuery().getTransformClause() != null) {
7836                                        subquerys.add(stmt.getSubQuery());
7837                                } else if (stmt.getSubQuery().getValueClause() != null
7838                                                && stmt.getSubQuery().getValueClause().getRows() != null) {
7839                                        for (TResultColumnList resultColumnList : stmt.getSubQuery().getValueClause().getRows()) {
7840                                                for(TResultColumn resultColumn: resultColumnList) {
7841                                                        if(resultColumn.getExpr()!=null && resultColumn.getExpr().getSubQuery()!=null) {
7842                                                                analyzeSelectStmt(resultColumn.getExpr().getSubQuery());
7843                                                                subquerys.add(resultColumn.getExpr().getSubQuery());
7844                                                        }
7845                                                }
7846                                        }
7847                                }
7848
7849                                for(TSelectSqlStatement subquery: subquerys) {
7850                                        if ((tableModel.isCreateTable() && tableModel.getColumns() != null)
7851                                                        || (subquery.getSetOperatorType() == ESetOperatorType.none
7852                                                                        && stmt.getColumnList() != null && stmt.getColumnList().size() > 0)) {
7853
7854                                                ResultSet resultSetModel = null;
7855
7856                                                if (subquery != null) {
7857                                                        resultSetModel = (ResultSet) modelManager.getModel(subquery);
7858                                                }
7859
7860                                                TResultColumnList resultset = subquery.getResultColumnList();
7861                                                if (resultSetModel == null && resultset != null) {
7862                                                        resultSetModel = (ResultSet) modelManager.getModel(resultset);
7863                                                }
7864
7865                                                if (resultSetModel == null) {
7866                                                        ErrorInfo errorInfo = new ErrorInfo();
7867                                                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7868                                                        errorInfo.setErrorMessage("Can't get resultset model");
7869                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(resultset.getStartToken().lineNo,
7870                                                                        resultset.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7871                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(resultset.getEndToken().lineNo,
7872                                                                        resultset.getEndToken().columnNo + resultset.getEndToken().astext.length(),
7873                                                                        ModelBindingManager.getGlobalHash()));
7874                                                        errorInfos.add(errorInfo);
7875                                                }
7876
7877                                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
7878                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
7879                                                        impactRelation.setEffectType(effectType);
7880                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
7881                                                                        resultSetModel.getRelationRows()));
7882                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
7883                                                                        tableModel.getRelationRows()));
7884                                                }
7885
7886                                                int resultSetSize = resultSetModel.getColumns().size();
7887                                                int j = 0;
7888                                                int starIndex = 0;
7889                                                TObjectNameList items = stmt.getColumnList();
7890                                                List<String> itemNames = new ArrayList<String>();
7891                                                if (items != null) {
7892                                                        for (int i = 0; i < items.size() && j < resultSetSize; i++) {
7893                                                                TObjectName column = items.getObjectName(i);
7894
7895                                                                if (column.getDbObjectType() == EDbObjectType.variable) {
7896                                                                        continue;
7897                                                                }
7898
7899                                                                if (column.getColumnNameOnly().startsWith("@")
7900                                                                                && (option.getVendor() == EDbVendor.dbvmssql
7901                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
7902                                                                        continue;
7903                                                                }
7904
7905                                                                if (column.getColumnNameOnly().startsWith(":")
7906                                                                                && (option.getVendor() == EDbVendor.dbvhana
7907                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
7908                                                                        continue;
7909                                                                }
7910
7911                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
7912                                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
7913                                                                        j++;
7914                                                                } else {
7915                                                                        starIndex++;
7916                                                                        if (resultSetSize - j == items.size() - i) {
7917                                                                                j++;
7918
7919                                                                        }
7920                                                                }
7921                                                                if (column != null) {
7922                                                                        TableColumn tableColumn;
7923                                                                        // if (!initColumn) {
7924                                                                        tableColumn = matchColumn(tableModel.getColumns(), column);
7925                                                                        if (tableColumn == null) {
7926                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
7927                                                                                        if (tableModel.getColumns().size() <= i) {
7928                                                                                                continue;
7929                                                                                        }
7930                                                                                        tableColumn = tableModel.getColumns().get(i);
7931                                                                                } else {
7932                                                                                        tableColumn = modelFactory.createTableColumn(tableModel, column, false);
7933                                                                                        if(tableColumn == null) {
7934                                                                                                continue;
7935                                                                                        }
7936                                                                                }
7937                                                                        }
7938//                                                      } else {
7939//                                                              tableColumn = matchColumn(tableColumns, column);
7940//                                                              if (tableColumn == null) {
7941//                                                                      continue;
7942//                                                              }
7943//                                                      }
7944                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7945                                                                        relation.setEffectType(effectType);
7946                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7947                                                                        if (resultColumn.hasStarLinkColumn()
7948                                                                                        && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
7949                                                                                while (resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
7950                                                                                        TObjectName name = resultColumn.getStarLinkColumnName(starIndex - 1);
7951                                                                                        if (itemNames.contains(name.toString())) {
7952                                                                                                starIndex++;
7953                                                                                                continue;
7954                                                                                        }
7955                                                                                        ResultColumn expandStarColumn = modelFactory
7956                                                                                                        .createResultColumn(resultSetModel, name, false);
7957                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
7958                                                                                        itemNames.add(resultColumn.getName());
7959                                                                                        break;
7960                                                                                }
7961                                                                        } else {
7962                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7963                                                                                itemNames.add(resultColumn.getName());
7964                                                                        }
7965                                                                        Process process = modelFactory.createProcess(stmt);
7966                                                                        relation.setProcess(process);
7967                                                                }
7968                                                        }
7969                                                } else {
7970                                                        List<TableColumn> columns = tableModel.getColumns();
7971                                                        if (columns.size() == 1 && tableModel.isPath()) {
7972                                                                for(int i=0;i<resultSetSize;i++) {
7973                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
7974                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7975                                                                        relation.setEffectType(effectType);
7976                                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(0)));
7977                                                                        if (resultColumn.hasStarLinkColumn()
7978                                                                                        && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
7979                                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(
7980                                                                                                resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
7981                                                                                                false);
7982                                                                                relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
7983                                                                        } else {
7984                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7985                                                                        }
7986                                                                        Process process = modelFactory.createProcess(stmt);
7987                                                                        relation.setProcess(process);
7988                                                                }
7989                                                        } else {
7990                                                                boolean fromStruct = false;
7991                                                                for (int i = 0; i < columns.size() && j < resultSetSize; i++) {
7992                                                                        String column = columns.get(i).getName();
7993                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
7994                                                                        if (!resultColumn.getName().contains("*")) {
7995                                                                                if (resultColumn.getName().equals(resultColumn.getRefColumnName())
7996                                                                                                && resultColumn.getColumnObject().toString().endsWith("*")
7997                                                                                                && resultSetSize == 1) {
7998                                                                                        starIndex++;
7999                                                                                        if (resultSetSize - j == columns.size() - i) {
8000                                                                                                j++;
8001
8002                                                                                        }
8003                                                                                }
8004                                                                                else {
8005                                                                                        j++;
8006                                                                                }
8007                                                                        } else {
8008                                                                                starIndex++;
8009                                                                                if (resultSetSize - j == columns.size() - i) {
8010                                                                                        j++;
8011
8012                                                                                }
8013                                                                        }
8014                                                                        if (column != null) {
8015                                                                                TableColumn tableColumn;
8016                                                                                // if (!initColumn) {
8017                                                                                tableColumn = matchColumn(tableModel.getColumns(), columns.get(i));
8018                                                                                if (tableColumn == null) {
8019                                                                                        if (tableModel.isCreateTable()
8020                                                                                                        && !containStarColumn(tableModel.getColumns())) {
8021                                                                                                if (tableModel.getColumns().size() <= i) {
8022                                                                                                        continue;
8023                                                                                                }
8024                                                                                                tableColumn = tableModel.getColumns().get(i);
8025                                                                                        } else {
8026                                                                                                TObjectName columnName = new TObjectName();
8027                                                                                                columnName.setString(column);
8028                                                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName,
8029                                                                                                                false);
8030                                                                                        }
8031                                                                                }
8032                                                                                else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) {
8033                                                                                        j--;
8034                                                                                        fromStruct = true;
8035                                                                                }
8036                                                                                if(fromStruct && !tableColumn.isStruct()) {
8037                                                                                        fromStruct = false;
8038                                                                                        resultColumn = resultSetModel.getColumns().get(j);
8039                                                                                        j++;
8040                                                                                }
8041                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8042                                                                                relation.setEffectType(effectType);
8043                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8044                                                                                if (resultColumn.hasStarLinkColumn()
8045                                                                                                && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8046                                                                                        ResultColumn expandStarColumn = modelFactory.createResultColumn(
8047                                                                                                        resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
8048                                                                                                        false);
8049                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8050                                                                                } else {
8051                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1));
8052                                                                                }
8053                                                                                Process process = modelFactory.createProcess(stmt);
8054                                                                                relation.setProcess(process);
8055                                                                        }
8056                                                                }
8057                                                        }
8058                                                }
8059                                        } else if (!subquery.isCombinedQuery()) {
8060                                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
8061                                                                .getModel(subquery.getResultColumnList() != null ? subquery.getResultColumnList()
8062                                                                                : subquery.getTransformClause());
8063
8064                                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
8065                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
8066                                                        impactRelation.setEffectType(effectType);
8067                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
8068                                                                        resultSetModel.getRelationRows()));
8069                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
8070                                                                        tableModel.getRelationRows()));
8071                                                }
8072
8073                                                List<ResultColumn> columnsSnapshot = new ArrayList<ResultColumn>();
8074                                                columnsSnapshot.addAll(resultSetModel.getColumns());
8075                                                if(resultSetModel.isDetermined() && stmt.getColumnList() == null) {
8076                                                        tableModel.setDetermined(true);
8077                                                }
8078                                                for (int i = 0; i < columnsSnapshot.size(); i++) {
8079                                                        ResultColumn resultColumn = columnsSnapshot.get(i);
8080                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
8081                                                                TableColumn tableColumn;
8082                                                                if (!initColumn) {
8083                                                                        if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8084                                                                                if (tableModel.getColumns().size() <= i) {
8085                                                                                        continue;
8086                                                                                }
8087                                                                                tableColumn = tableModel.getColumns().get(i);
8088                                                                        } else {
8089                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8090                                                                                                (TObjectName) resultColumn.getColumnObject());
8091                                                                        }
8092                                                                        if (containStarColumn(tableColumns)) {
8093                                                                                getStarColumn(tableColumns)
8094                                                                                                .bindStarLinkColumn((TObjectName) resultColumn.getColumnObject());
8095                                                                        }
8096                                                                } else {
8097                                                                        TObjectName matchedColumnName = (TObjectName) resultColumn.getColumnObject();
8098                                                                        tableColumn = matchColumn(tableColumns, matchedColumnName);
8099                                                                        if (tableColumn == null) {
8100                                                                                if (!isEmptyCollection(valueMap)) {
8101                                                                                        int index = indexOfColumn(valueMap, matchedColumnName);
8102                                                                                        if (index != -1) {
8103                                                                                                if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8104                                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(index));
8105                                                                                                } else if (isEmptyCollection(keyMap) && index < tableColumns.size()) {
8106                                                                                                        tableColumn = tableColumns.get(index);
8107                                                                                                } else {
8108                                                                                                        continue;
8109                                                                                                }
8110                                                                                        } else {
8111                                                                                                continue;
8112                                                                                        }
8113                                                                                } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8114                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(i));
8115                                                                                } else if (isEmptyCollection(keyMap) && isEmptyCollection(valueMap)
8116                                                                                                && i < tableColumns.size()) {
8117                                                                                        tableColumn = tableColumns.get(i);
8118                                                                                } else {
8119                                                                                        continue;
8120                                                                                }
8121                                                                        }
8122                                                                }
8123
8124                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8125                                                                relation.setEffectType(effectType);
8126                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8127                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8128                                                                Process process = modelFactory.createProcess(stmt);
8129                                                                relation.setProcess(process);
8130                                                        } else {
8131                                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
8132                                                                if (alias != null && alias.getAliasName() != null) {
8133                                                                        TableColumn tableColumn;
8134                                                                        if (!initColumn) {
8135                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8136                                                                                        if (tableModel.getColumns().size() <= i) {
8137                                                                                                if (tableModel.isPath()) {
8138                                                                                                        tableColumn = tableModel.getColumns().get(0);
8139                                                                                                } else {
8140                                                                                                        continue;
8141                                                                                                }
8142                                                                                        } else {
8143                                                                                                tableColumn = tableModel.getColumns().get(i);
8144                                                                                        }
8145                                                                                } else {
8146                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8147                                                                                                        alias.getAliasName());
8148                                                                                        if (containStarColumn(resultSetModel)) {
8149                                                                                                tableColumn.notBindStarLinkColumn(true);
8150                                                                                        }
8151                                                                                }
8152                                                                                if (containStarColumn(tableColumns)) {
8153                                                                                        getStarColumn(tableColumns).bindStarLinkColumn(alias.getAliasName());
8154                                                                                }
8155                                                                        } else {
8156                                                                                TObjectName matchedColumnName = alias.getAliasName();
8157                                                                                tableColumn = matchColumn(tableColumns, matchedColumnName);
8158                                                                                if (tableColumn == null) {
8159                                                                                        if (!isEmptyCollection(valueMap)) {
8160                                                                                                int index = indexOfColumn(valueMap, matchedColumnName);
8161                                                                                                if (index != -1) {
8162                                                                                                        if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8163                                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(index));
8164                                                                                                        } else if (isEmptyCollection(keyMap)
8165                                                                                                                        && index < tableColumns.size()) {
8166                                                                                                                tableColumn = tableColumns.get(index);
8167                                                                                                        } else {
8168                                                                                                                continue;
8169                                                                                                        }
8170                                                                                                } else {
8171                                                                                                        continue;
8172                                                                                                }
8173                                                                                        } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8174                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(i));
8175                                                                                        } else {
8176                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8177                                                                                                                alias.getAliasName());
8178                                                                                        }
8179                                                                                }
8180
8181                                                                        }
8182
8183                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8184                                                                        relation.setEffectType(effectType);
8185                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8186                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8187                                                                        Process process = modelFactory.createProcess(stmt);
8188                                                                        relation.setProcess(process);
8189
8190                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getFieldAttr() != null) {
8191                                                                        TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
8192                                                                                        .getFieldAttr();
8193
8194                                                                        Object model = modelManager.getModel( resultColumn.getColumnObject());
8195                                                                        
8196                                                                        TableColumn tableColumn;
8197                                                                        if (!initColumn) {
8198                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8199                                                                                        if (fieldAttr.toString().endsWith("*")) {
8200                                                                                                int starIndex = 0;
8201                                                                                                for (TableColumn column : tableModel.getColumns()) {
8202                                                                                                        starIndex++;
8203                                                                                                        DataFlowRelationship relation = modelFactory
8204                                                                                                                        .createDataFlowRelation();
8205                                                                                                        relation.setEffectType(effectType);
8206                                                                                                        relation.setTarget(new TableColumnRelationshipElement(column));
8207                                                                                                        if (resultColumn.getStarLinkColumnList().size() == tableModel
8208                                                                                                                        .getColumns().size()) {
8209                                                                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(
8210                                                                                                                                resultSetModel,
8211                                                                                                                                resultColumn.getStarLinkColumnList().get(starIndex - 1),
8212                                                                                                                                false);
8213                                                                                                                relation.addSource(
8214                                                                                                                                new ResultColumnRelationshipElement(expandStarColumn));
8215                                                                                                        } else {
8216                                                                                                                relation.addSource(
8217                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
8218                                                                                                        }
8219                                                                                                        Process process = modelFactory.createProcess(stmt);
8220                                                                                                        relation.setProcess(process);
8221                                                                                                }
8222                                                                                                continue;
8223                                                                                        }
8224                                                                                        if (tableModel.getColumns().size() <= i) {
8225                                                                                                continue;
8226                                                                                        }
8227                                                                                        tableColumn = tableModel.getColumns().get(i);
8228                                                                                } else {
8229                                                                                        if(model instanceof LinkedHashMap) {
8230                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model;
8231                                                                                                for(String key: resultColumns.keySet()) {
8232                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName());
8233                                                                                                        DataFlowRelationship relation = modelFactory
8234                                                                                                                        .createDataFlowRelation();
8235                                                                                                        relation.setEffectType(effectType);
8236                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8237                                                                                                        relation.addSource(
8238                                                                                                                        new ResultColumnRelationshipElement(resultColumns.get(key)));
8239                                                                                                        Process process = modelFactory.createProcess(stmt);
8240                                                                                                        relation.setProcess(process);
8241                                                                                                }
8242                                                                                                continue;
8243                                                                                        }
8244                                                                                        else {
8245                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel, fieldAttr);
8246                                                                                        }
8247                                                                                }
8248                                                                        } else {
8249                                                                                TObjectName matchedColumnName = fieldAttr;
8250                                                                                tableColumn = matchColumn(tableColumns, matchedColumnName);
8251                                                                                if (tableColumn == null) {
8252                                                                                        if (!isEmptyCollection(valueMap)) {
8253                                                                                                int index = indexOfColumn(valueMap, matchedColumnName);
8254                                                                                                if (index != -1) {
8255                                                                                                        if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8256                                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(index));
8257                                                                                                        } else if (isEmptyCollection(keyMap)
8258                                                                                                                        && index < tableColumns.size()) {
8259                                                                                                                tableColumn = tableColumns.get(index);
8260                                                                                                        } else {
8261                                                                                                                continue;
8262                                                                                                        }
8263                                                                                                } else {
8264                                                                                                        continue;
8265                                                                                                }
8266                                                                                        } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8267                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(i));
8268                                                                                        } else {
8269                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8270                                                                                                                fieldAttr);
8271                                                                                        }
8272                                                                                }
8273                                                                        }
8274
8275                                                                        if (!"*".equals(getColumnName(tableColumn.getColumnObject()))
8276                                                                                        && "*".equals(getColumnName(fieldAttr))) {
8277                                                                                TObjectName columnObject = fieldAttr;
8278                                                                                TTable sourceTable = columnObject.getSourceTable();
8279                                                                                if (columnObject.getTableToken() != null && sourceTable != null) {
8280                                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
8281                                                                                        for (int j = 0; j < columns.length; j++) {
8282                                                                                                TObjectName columnName = columns[j];
8283                                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
8284                                                                                                        continue;
8285                                                                                                }
8286                                                                                                resultColumn.bindStarLinkColumn(columnName);
8287                                                                                        }
8288                                                                                } else {
8289                                                                                        TTableList tables = stmt.getTables();
8290                                                                                        for (int k = 0; k < tables.size(); k++) {
8291                                                                                                TTable tableElement = tables.getTable(k);
8292                                                                                                TObjectName[] columns = modelManager.getTableColumns(tableElement);
8293                                                                                                for (int j = 0; j < columns.length; j++) {
8294                                                                                                        TObjectName columnName = columns[j];
8295                                                                                                        if (columnName == null || "*".equals(getColumnName(columnName))) {
8296                                                                                                                continue;
8297                                                                                                        }
8298                                                                                                        resultColumn.bindStarLinkColumn(columnName);
8299                                                                                                }
8300                                                                                        }
8301                                                                                }
8302                                                                        }
8303
8304                                                                        if ("*".equals(getColumnName(tableColumn.getColumnObject())) && resultColumn != null
8305                                                                                        && !resultColumn.getStarLinkColumns().isEmpty()) {
8306                                                                                tableColumn.bindStarLinkColumns(resultColumn.getStarLinkColumns());
8307                                                                        }
8308
8309                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8310                                                                        relation.setEffectType(effectType);
8311                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8312                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8313
8314                                                                        if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
8315                                                                                tableColumn.getTable().setStarStmt("insert");
8316                                                                        }
8317
8318                                                                        Process process = modelFactory.createProcess(stmt);
8319                                                                        relation.setProcess(process);
8320                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
8321                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
8322                                                                        if (!initColumn) {
8323                                                                                TableColumn tableColumn;
8324                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8325                                                                                        if (tableModel.getColumns().size() <= i) {
8326                                                                                                continue;
8327                                                                                        }
8328                                                                                        tableColumn = tableModel.getColumns().get(i);
8329                                                                                } else {
8330                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8331                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
8332                                                                                                                        .getConstantOperand(),
8333                                                                                                        i);
8334                                                                                }
8335
8336                                                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
8337                                                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
8338                                                                                        TSQLSchema schema = sqlenv.getSQLSchema(
8339                                                                                                        tableModel.getDatabase() + "." + tableModel.getSchema(), true);
8340                                                                                        if (schema != null) {
8341                                                                                                TSQLTable tempTable = schema.createTable(
8342                                                                                                                DlineageUtil.getSimpleTableName(tableModel.getName()));
8343                                                                                                tempTable.addColumn(tableColumn.getName());
8344                                                                                        }
8345                                                                                }
8346                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8347                                                                                relation.setEffectType(effectType);
8348                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8349                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8350                                                                                Process process = modelFactory.createProcess(stmt);
8351                                                                                relation.setProcess(process);
8352                                                                        } else {
8353                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8354                                                                                relation.setEffectType(effectType);
8355                                                                                relation.setTarget(
8356                                                                                                new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
8357                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8358                                                                                Process process = modelFactory.createProcess(stmt);
8359                                                                                relation.setProcess(process);
8360                                                                        }
8361                                                                } else {
8362                                                                        if (!initColumn) {
8363                                                                                TableColumn tableColumn;
8364                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8365                                                                                        if (tableModel.getColumns().size() <= i) {
8366                                                                                                continue;
8367                                                                                        }
8368                                                                                        tableColumn = tableModel.getColumns().get(i);
8369                                                                                } else {
8370                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8371                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i);
8372                                                                                }
8373                                                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
8374                                                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
8375                                                                                        TSQLSchema schema = sqlenv.getSQLSchema(
8376                                                                                                        tableModel.getDatabase() + "." + tableModel.getSchema(), true);
8377                                                                                        if (schema != null) {
8378                                                                                                TSQLTable tempTable = schema.createTable(
8379                                                                                                                DlineageUtil.getSimpleTableName(tableModel.getName()));
8380                                                                                                tempTable.addColumn(tableColumn.getName());
8381                                                                                        }
8382                                                                                }
8383                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8384                                                                                relation.setEffectType(effectType);
8385                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8386                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8387                                                                                Process process = modelFactory.createProcess(stmt);
8388                                                                                relation.setProcess(process);
8389                                                                        } else {
8390                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8391                                                                                relation.setEffectType(effectType);
8392                                                                                relation.setTarget(
8393                                                                                                new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
8394                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8395                                                                                Process process = modelFactory.createProcess(stmt);
8396                                                                                relation.setProcess(process);
8397                                                                        }
8398                                                                }
8399                                                        }
8400                                                }
8401                                        } else if (stmt.getSubQuery() != null) {
8402                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
8403                                                if (resultSetModel != null) {
8404
8405                                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
8406                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
8407                                                                impactRelation.setEffectType(effectType);
8408                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
8409                                                                                resultSetModel.getRelationRows()));
8410                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
8411                                                                                tableModel.getRelationRows()));
8412                                                        }
8413
8414                                                        if(stmt.getColumnList()!=null && stmt.getColumnList().size()>0) {
8415                                                                for(int i=0;i<stmt.getColumnList().size();i++) {
8416                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8417                                                                                        stmt.getColumnList().getObjectName(i));
8418                                                                }
8419                                                                
8420                                                                List<TableColumn> columns = tableModel.getColumns();
8421                                                                int resultSetSize = resultSetModel.getColumns().size();
8422                                                                int starIndex = 0; 
8423                                                                int j = 0;
8424                                                                boolean fromStruct = false;
8425                                                                for (int i = 0; i < columns.size() && j < resultSetSize; i++) {
8426                                                                        String column = columns.get(i).getName();
8427                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
8428                                                                        if (!resultColumn.getName().contains("*")) {
8429                                                                                if (resultColumn.getName().equals(resultColumn.getRefColumnName())
8430                                                                                                && resultColumn.getColumnObject().toString().endsWith("*")
8431                                                                                                && resultSetSize == 1) {
8432                                                                                        starIndex++;
8433                                                                                        if (resultSetSize - j == columns.size() - i) {
8434                                                                                                j++;
8435
8436                                                                                        }
8437                                                                                }
8438                                                                                else {
8439                                                                                        j++;
8440                                                                                }
8441                                                                        } else {
8442                                                                                starIndex++;
8443                                                                                if (resultSetSize - j == columns.size() - i) {
8444                                                                                        j++;
8445
8446                                                                                }
8447                                                                        }
8448                                                                        if (column != null) {
8449                                                                                TableColumn tableColumn;
8450                                                                                // if (!initColumn) {
8451                                                                                tableColumn = matchColumn(tableModel.getColumns(), columns.get(i));
8452                                                                                if (tableColumn == null) {
8453                                                                                        if (tableModel.isCreateTable()
8454                                                                                                        && !containStarColumn(tableModel.getColumns())) {
8455                                                                                                if (tableModel.getColumns().size() <= i) {
8456                                                                                                        continue;
8457                                                                                                }
8458                                                                                                tableColumn = tableModel.getColumns().get(i);
8459                                                                                        } else {
8460                                                                                                TObjectName columnName = new TObjectName();
8461                                                                                                columnName.setString(column);
8462                                                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName,
8463                                                                                                                false);
8464                                                                                        }
8465                                                                                }
8466                                                                                else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) {
8467                                                                                        j--;
8468                                                                                        fromStruct = true;
8469                                                                                }
8470                                                                                if(fromStruct && !tableColumn.isStruct()) {
8471                                                                                        fromStruct = false;
8472                                                                                        resultColumn = resultSetModel.getColumns().get(j);
8473                                                                                        j++;
8474                                                                                }
8475                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8476                                                                                relation.setEffectType(effectType);
8477                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8478                                                                                if (resultColumn.hasStarLinkColumn()
8479                                                                                                && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8480                                                                                        ResultColumn expandStarColumn = modelFactory.createResultColumn(
8481                                                                                                        resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
8482                                                                                                        false);
8483                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8484                                                                                } else {
8485                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1));
8486                                                                                }
8487                                                                                Process process = modelFactory.createProcess(stmt);
8488                                                                                relation.setProcess(process);
8489                                                                        }
8490                                                                }
8491                                                        }
8492                                                        else {
8493                                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
8494                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
8495                                                                        TAliasClause alias = null;
8496                                                                        if(resultColumn.getColumnObject() instanceof TResultColumn) {
8497                                                                                alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
8498                                                                        }
8499                                                                        if (stmt.getColumnList() != null) {
8500                                                                                if (i < stmt.getColumnList().size()) {
8501                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8502                                                                                        relation.setEffectType(effectType);
8503                                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8504                                                                                                        stmt.getColumnList().getObjectName(i));
8505                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8506                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8507                                                                                        Process process = modelFactory.createProcess(stmt);
8508                                                                                        relation.setProcess(process);
8509                                                                                }
8510                                                                        } else {
8511                                                                                if (alias != null && alias.getAliasName() != null) {
8512                                                                                        TableColumn tableColumn;
8513                                                                                        if (!initColumn) {
8514                                                                                                if (tableModel.isCreateTable()
8515                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8516                                                                                                        if (tableModel.getColumns().size() <= i) {
8517                                                                                                                continue;
8518                                                                                                        }
8519                                                                                                        tableColumn = tableModel.getColumns().get(i);
8520                                                                                                } else {
8521                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8522                                                                                                                        alias.getAliasName());
8523                                                                                                }
8524                                                                                        } else {
8525                                                                                                tableColumn = matchColumn(tableColumns, alias.getAliasName());
8526                                                                                                if (tableColumn == null) {
8527                                                                                                        continue;
8528                                                                                                }
8529                                                                                        }
8530        
8531                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8532                                                                                        relation.setEffectType(effectType);
8533                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8534                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8535                                                                                        Process process = modelFactory.createProcess(stmt);
8536                                                                                        relation.setProcess(process);
8537                                                                                } else if (resultColumn.getColumnObject() instanceof TObjectName 
8538                                                                                                || ( resultColumn.getColumnObject() instanceof TResultColumn && ((TResultColumn) resultColumn.getColumnObject())
8539                                                                                                .getFieldAttr() != null)) {
8540                                                                                        TObjectName fieldAttr = null;
8541                                                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
8542                                                                                                fieldAttr = (TObjectName)resultColumn.getColumnObject();
8543                                                                                        }
8544                                                                                        else if (resultColumn.getColumnObject() instanceof TResultColumn) {
8545                                                                                                fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
8546                                                                                                                .getFieldAttr();
8547                                                                                        }
8548                                
8549                                                                                        TableColumn tableColumn;
8550                                                                                        if (!initColumn) {
8551                                                                                                if (tableModel.isCreateTable()
8552                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8553                                                                                                        if (tableModel.getColumns().size() <= i) {
8554                                                                                                                continue;
8555                                                                                                        }
8556                                                                                                        tableColumn = tableModel.getColumns().get(i);
8557                                                                                                } else {
8558                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8559                                                                                                                        fieldAttr);
8560                                                                                                }
8561                                                                                        } else {
8562                                                                                                tableColumn = matchColumn(tableColumns, fieldAttr);
8563                                                                                                if (tableColumn == null) {
8564                                                                                                        continue;
8565                                                                                                }
8566                                                                                        }
8567        
8568                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8569                                                                                        relation.setEffectType(effectType);
8570                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8571                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8572                                                                                        Process process = modelFactory.createProcess(stmt);
8573                                                                                        relation.setProcess(process);
8574                                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
8575                                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
8576                                                                                        if (!initColumn) {
8577                                                                                                TableColumn tableColumn;
8578                                                                                                if (tableModel.isCreateTable()
8579                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8580                                                                                                        if (tableModel.getColumns().size() <= i) {
8581                                                                                                                continue;
8582                                                                                                        }
8583                                                                                                        tableColumn = tableModel.getColumns().get(i);
8584                                                                                                } else {
8585                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8586                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
8587                                                                                                                                        .getConstantOperand(),
8588                                                                                                                        i);
8589                                                                                                }
8590                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8591                                                                                                relation.setEffectType(effectType);
8592                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8593                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8594                                                                                                Process process = modelFactory.createProcess(stmt);
8595                                                                                                relation.setProcess(process);
8596                                                                                        }
8597                                                                                } else {
8598                                                                                        if (!initColumn) {
8599                                                                                                TableColumn tableColumn;
8600                                                                                                if (tableModel.isCreateTable()
8601                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8602                                                                                                        if (tableModel.getColumns().size() <= i) {
8603                                                                                                                continue;
8604                                                                                                        }
8605                                                                                                        tableColumn = tableModel.getColumns().get(i);
8606                                                                                                } else {
8607                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8608                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i);
8609                                                                                                }
8610                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8611                                                                                                relation.setEffectType(effectType);
8612                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8613                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8614                                                                                                Process process = modelFactory.createProcess(stmt);
8615                                                                                                relation.setProcess(process);
8616                                                                                        }
8617                                                                                }
8618                                                                        }
8619                                                                }
8620                                                        }
8621                                                }
8622                                        }
8623                                }
8624                        } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
8625                                TObjectNameList items = stmt.getColumnList();
8626                                TMultiTargetList values = stmt.getValues();
8627                                if (values != null) {
8628                                        for (int k = 0; values != null && k < values.size(); k++) {
8629                                                int j = 0;
8630                                                for (int i = 0; i < items.size(); i++) {
8631                                                        TObjectName column = items.getObjectName(i);
8632                                                        TableColumn tableColumn;
8633                                                        if (!initColumn) {
8634                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8635                                                                        if (tableModel.getColumns().size() <= i) {
8636                                                                                continue;
8637                                                                        }
8638                                                                        tableColumn = tableModel.getColumns().get(i);
8639                                                                } else {
8640                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, column);
8641                                                                }
8642                                                        } else {
8643                                                                tableColumn = matchColumn(tableColumns, column);
8644                                                                if (tableColumn == null) {
8645                                                                        continue;
8646                                                                }
8647                                                        }
8648                                                        TResultColumn columnObject = values.getMultiTarget(k).getColumnList().getResultColumn(j);
8649                                                        if (columnObject == null) {
8650                                                                continue;
8651                                                        }
8652                                                        TExpression valueExpr = columnObject.getExpr();
8653                                                        columnsInExpr visitor = new columnsInExpr();
8654                                                        valueExpr.inOrderTraverse(visitor);
8655                                                        List<TObjectName> objectNames = visitor.getObjectNames();
8656                                                        List<TParseTreeNode> constants = visitor.getConstants();
8657                                                        List<TParseTreeNode> functions = visitor.getFunctions();
8658                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
8659
8660                                                        Process process = modelFactory.createProcess(stmt);
8661                                                        
8662                                                        
8663                                                        
8664                                                        if (functions != null && !functions.isEmpty()) {
8665                                                                analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process);
8666                                                        }
8667
8668                                                        if (subquerys != null && !subquerys.isEmpty()) {
8669                                                                analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process);
8670                                                        }
8671                                                        if (objectNames != null && !objectNames.isEmpty()) {
8672                                                                analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions,
8673                                                                                process, i);
8674                                                        }
8675                                                        //insert into values generate too many constant relations, ignore constant relations.
8676                                                        if (constants != null && !constants.isEmpty()) {
8677                                                                if (!option.isIgnoreInsertIntoValues() || stmt.getParentStmt() != null) {
8678                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, effectType,
8679                                                                                        functions, process);
8680                                                                }
8681                                                        }
8682                                                        j++;
8683                                                }
8684                                        }
8685                                } else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) {
8686                                        analyzeCustomSqlStmt(stmt.getExecuteStmt());
8687                                        Procedure procedure = modelManager.getProcedureByName(DlineageUtil
8688                                                        .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString()));
8689                                        if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) {
8690                                                TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure
8691                                                                .getProcedureObject();
8692                                                List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt);
8693                                                if (stmtItems != null) {
8694                                                        for(TSelectSqlStatement stmtItem: stmtItems) {
8695                                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem);
8696                                                                if (resultSetModel != null) {
8697                                                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
8698                                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
8699                                                                                Transform transform = new Transform();
8700                                                                                transform.setType(Transform.FUNCTION);
8701                                                                                transform.setCode(stmt.getExecuteStmt().getModuleName());
8702                                                                                resultColumn.setTransform(transform);
8703                                                                                
8704                                                                                if (stmt.getColumnList() != null) {
8705                                                                                        if (i < stmt.getColumnList().size()) {
8706                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8707                                                                                                relation.setEffectType(effectType);
8708                                                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8709                                                                                                                stmt.getColumnList().getObjectName(i));                                                                                         
8710                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8711                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8712                                                                                                Process process = modelFactory.createProcess(stmt);
8713                                                                                                relation.setProcess(process);                                   
8714                                                                                        }
8715                                                                                } else {
8716                                                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
8717                                                                                                TObjectName fieldAttr = ((TObjectName) resultColumn.getColumnObject());
8718                                                                                                TableColumn tableColumn;
8719                                                                                                if (!initColumn) {
8720                                                                                                        if (tableModel.isCreateTable()
8721                                                                                                                        && !containStarColumn(tableModel.getColumns())) {
8722                                                                                                                if (tableModel.getColumns().size() <= i) {
8723                                                                                                                        continue;
8724                                                                                                                }
8725                                                                                                                tableColumn = tableModel.getColumns().get(i);
8726                                                                                                        } else {
8727                                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8728                                                                                                                                fieldAttr);
8729                                                                                                        }
8730                                                                                                } else {
8731                                                                                                        tableColumn = matchColumn(tableColumns, fieldAttr);
8732                                                                                                        if (tableColumn == null) {
8733                                                                                                                continue;
8734                                                                                                        }
8735                                                                                                }
8736        
8737                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8738                                                                                                relation.setEffectType(effectType);
8739                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8740                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8741                                                                                                Process process = modelFactory.createProcess(stmt);
8742                                                                                                relation.setProcess(process);
8743
8744                                                                                                
8745                                                                                        } else {
8746                                                                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject())
8747                                                                                                                .getAliasClause();
8748                                                                                                if (alias != null && alias.getAliasName() != null) {
8749                                                                                                        TableColumn tableColumn;
8750                                                                                                        if (!initColumn) {
8751                                                                                                                if (tableModel.isCreateTable()
8752                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8753                                                                                                                        if (tableModel.getColumns().size() <= i) {
8754                                                                                                                                continue;
8755                                                                                                                        }
8756                                                                                                                        tableColumn = tableModel.getColumns().get(i);
8757                                                                                                                } else {
8758                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8759                                                                                                                                        alias.getAliasName());
8760                                                                                                                }
8761                                                                                                        } else {
8762                                                                                                                tableColumn = matchColumn(tableColumns, alias.getAliasName());
8763                                                                                                                if (tableColumn == null) {
8764                                                                                                                        continue;
8765                                                                                                                }
8766                                                                                                        }
8767                                                                                                        
8768                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8769                                                                                                        relation.setEffectType(effectType);
8770                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8771                                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8772                                                                                                        Process process = modelFactory.createProcess(stmt);
8773                                                                                                        relation.setProcess(process);
8774                                                                                                } else if (((TResultColumn) resultColumn.getColumnObject())
8775                                                                                                                .getFieldAttr() != null) {
8776                                                                                                        TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
8777                                                                                                                        .getFieldAttr();
8778                                                                                                        TableColumn tableColumn;
8779                                                                                                        if (!initColumn) {
8780                                                                                                                if (tableModel.isCreateTable()
8781                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8782                                                                                                                        if (tableModel.getColumns().size() <= i) {
8783                                                                                                                                continue;
8784                                                                                                                        }
8785                                                                                                                        tableColumn = tableModel.getColumns().get(i);
8786                                                                                                                } else {
8787                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8788                                                                                                                                        fieldAttr);
8789                                                                                                                }
8790                                                                                                        } else {
8791                                                                                                                tableColumn = matchColumn(tableColumns, fieldAttr);
8792                                                                                                                if (tableColumn == null) {
8793                                                                                                                        continue;
8794                                                                                                                }
8795                                                                                                        }
8796                                                                                                        
8797                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8798                                                                                                        relation.setEffectType(effectType);
8799                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8800                                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8801                                                                                                        Process process = modelFactory.createProcess(stmt);
8802                                                                                                        relation.setProcess(process);                                                                                                   
8803                                                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
8804                                                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
8805                                                                                                        if (!initColumn) {
8806                                                                                                                TableColumn tableColumn;
8807                                                                                                                if (tableModel.isCreateTable()
8808                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8809                                                                                                                        if (tableModel.getColumns().size() <= i) {
8810                                                                                                                                continue;
8811                                                                                                                        }
8812                                                                                                                        tableColumn = tableModel.getColumns().get(i);
8813                                                                                                                } else {
8814                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8815                                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
8816                                                                                                                                                        .getConstantOperand(),
8817                                                                                                                                        i);
8818                                                                                                                }
8819                                                                                                                
8820                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8821                                                                                                                relation.setEffectType(effectType);
8822                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8823                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8824                                                                                                                Process process = modelFactory.createProcess(stmt);
8825                                                                                                                relation.setProcess(process);
8826                                                                                                        }
8827                                                                                                } else {
8828                                                                                                        if (!initColumn) {
8829                                                                                                                TableColumn tableColumn;
8830                                                                                                                if (tableModel.isCreateTable()
8831                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
8832                                                                                                                        if (tableModel.getColumns().size() <= i) {
8833                                                                                                                                continue;
8834                                                                                                                        }
8835                                                                                                                        tableColumn = tableModel.getColumns().get(i);
8836                                                                                                                } else {
8837                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8838                                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(),
8839                                                                                                                                        i);
8840                                                                                                                }
8841                                                                                                                
8842                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8843                                                                                                                relation.setEffectType(effectType);
8844                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8845                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8846                                                                                                                Process process = modelFactory.createProcess(stmt);
8847                                                                                                                relation.setProcess(process);
8848                                                                                                        }
8849                                                                                                }
8850                                                                                        }
8851                                                                                }
8852                                                                        }
8853                                                                }
8854                                                        }
8855                                                }
8856                                        }
8857                                        else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) {
8858                                                TObjectName functionName = new TObjectName();
8859                                                functionName.setString(procedure.getProcedureObject().toString());
8860                                                Function function = (Function)createFunction(functionName);
8861                                                if (stmt.getColumnList() != null) {
8862                                                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
8863                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8864                                                                relation.setEffectType(effectType);
8865                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8866                                                                                stmt.getColumnList().getObjectName(i));
8867                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8868                                                                relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
8869                                                                Process process = modelFactory.createProcess(stmt);
8870                                                                relation.setProcess(process);
8871                                                        }
8872                                                }
8873                                        }
8874                                }
8875                        } else if (stmt.getValues() != null && stmt.getValues().size() > 0 && tableModel.isCreateTable()) {
8876                                for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) {
8877                                        TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList();
8878                                        boolean allConstant = true;
8879                                        Process process = modelFactory.createProcess(stmt);
8880                                        for (int x = 0; x < columns.size(); x++) {
8881                                                TableColumn tableColumn = tableModel.getColumns().get(x);
8882                                                TResultColumn columnObject = columns.getResultColumn(x);
8883                                                if (columnObject == null) {
8884                                                        continue;
8885                                                }
8886                                                TExpression valueExpr = columnObject.getExpr();
8887                                                columnsInExpr visitor = new columnsInExpr();
8888                                                valueExpr.inOrderTraverse(visitor);
8889                                                List<TObjectName> objectNames = visitor.getObjectNames();
8890                                                List<TParseTreeNode> constants = visitor.getConstants();
8891                                                List<TParseTreeNode> functions = visitor.getFunctions();
8892                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
8893
8894                                                if (functions != null && !functions.isEmpty()) {
8895                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process);
8896                                                }
8897
8898                                                if (subquerys != null && !subquerys.isEmpty()) {
8899                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process);
8900                                                }
8901                                                if (objectNames != null && !objectNames.isEmpty()) {
8902                                                        analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions,
8903                                                                        process);
8904                                                }
8905                                                //insert into values generate too many constant relations, ignore constant relations.
8906                                                if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) {
8907                                                        analyzeConstantDataFlowRelation(tableColumn, constants, effectType, functions,
8908                                                                        process);
8909                                                        allConstant = false;
8910                                                }
8911                                                else {
8912                                                        allConstant = true;
8913                                                }
8914                                        }
8915                                        
8916                                        if(allConstant) {
8917                                                modelManager.unbindProcessModel(stmt);
8918                                                tableModel.removeProcess(process);
8919                                        }
8920                                }
8921                        } else if (stmt.getRecordName() != null) {
8922                                String procedureName = DlineageUtil.getProcedureParentName(stmt);
8923                                String variableString = stmt.getRecordName().toString();
8924                                if (variableString.startsWith(":")) {
8925                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
8926                                }
8927                                if (!SQLUtil.isEmpty(procedureName)) {
8928                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
8929                                }
8930                                
8931                                Table recordTable = modelManager
8932                                                .getTableByName(DlineageUtil.getTableFullName(variableString));
8933                                if (recordTable != null) {
8934                                        for (int i = 0; i < recordTable.getColumns().size(); i++) {
8935                                                TableColumn sourceTableColumn = recordTable.getColumns().get(i);
8936                                                TableColumn targetTableColumn = modelFactory.createTableColumn(tableModel,
8937                                                                sourceTableColumn.getColumnObject(), false);
8938                                                if (targetTableColumn != null) {
8939                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8940                                                        relation.setEffectType(effectType);
8941                                                        relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
8942                                                        relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
8943                                                        Process process = modelFactory.createProcess(stmt);
8944                                                        relation.setProcess(process);
8945                                                } else if (sourceTableColumn.getName().endsWith("*") && tableModel.isCreateTable()) {
8946                                                        for (TableColumn column : tableModel.getColumns()) {
8947                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8948                                                                relation.setEffectType(effectType);
8949                                                                relation.setTarget(new TableColumnRelationshipElement(column));
8950                                                                relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
8951                                                                Process process = modelFactory.createProcess(stmt);
8952                                                                relation.setProcess(process);
8953                                                        }
8954                                                }
8955                                        }
8956                                }
8957                        } else if (stmt.getInsertSource() == EInsertSource.values_function && stmt.getFunctionCall() != null) {
8958                                Table cursor = modelManager.getTableByName(
8959                                                DlineageUtil.getTableFullName(stmt.getFunctionCall().getFunctionName().toString()));
8960                                if (cursor != null) {
8961                                        TObjectName starColumn = new TObjectName();
8962                                        starColumn.setString("*");
8963                                        TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
8964                                        insertColumn.setShowStar(false);
8965                                        insertColumn.setExpandStar(true);
8966                                        for (int j = 0; j < cursor.getColumns().size(); j++) {
8967                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
8968                                                dataflowRelation.setEffectType(effectType);
8969                                                dataflowRelation.addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j)));
8970                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(insertColumn));
8971                                                Process process = modelFactory.createProcess(stmt);
8972                                                dataflowRelation.setProcess(process);
8973                                        }
8974                                }
8975
8976                        } else if (stmt.getInsertSource() == EInsertSource.values && stmt.getValues() != null) {
8977                                TObjectName starColumn = new TObjectName();
8978                                starColumn.setString("*");
8979                                TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
8980                                insertColumn.setShowStar(false);
8981                                insertColumn.setExpandStar(true);
8982                                for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) {
8983                                        TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList();
8984                                        for (int x = 0; x < columns.size(); x++) {
8985                                                TResultColumn columnObject = columns.getResultColumn(x);
8986                                                if (columnObject == null) {
8987                                                        continue;
8988                                                }
8989                                                TExpression valueExpr = columnObject.getExpr();
8990                                                columnsInExpr visitor = new columnsInExpr();
8991                                                valueExpr.inOrderTraverse(visitor);
8992                                                List<TObjectName> objectNames = visitor.getObjectNames();
8993                                                List<TParseTreeNode> constants = visitor.getConstants();
8994                                                List<TParseTreeNode> functions = visitor.getFunctions();
8995                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
8996
8997                                                Process process = modelFactory.createProcess(stmt);
8998                                                if (functions != null && !functions.isEmpty()) {
8999                                                        analyzeFunctionDataFlowRelation(insertColumn, functions, effectType, process);
9000                                                }
9001
9002                                                if (subquerys != null && !subquerys.isEmpty()) {
9003                                                        analyzeSubqueryDataFlowRelation(insertColumn, subquerys, effectType, process);
9004                                                }
9005                                                if (objectNames != null && !objectNames.isEmpty()) {
9006                                                        analyzeDataFlowRelation(insertColumn, objectNames, null, effectType, functions,
9007                                                                        process);
9008                                                }
9009                                                //insert into values generate too many constant relations, ignore constant relations.
9010                                                if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) {
9011                                                        analyzeConstantDataFlowRelation(insertColumn, constants, effectType, functions,
9012                                                                        process);
9013                                                }
9014                                        }
9015                                }
9016                        }else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) {
9017                                analyzeCustomSqlStmt(stmt.getExecuteStmt());
9018                                Procedure procedure = modelManager.getProcedureByName(DlineageUtil
9019                                                .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString()));
9020                                if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) {
9021                                        TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure
9022                                                        .getProcedureObject();
9023                                        List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt);
9024                                        if (stmtItems != null) {
9025                                                for(TSelectSqlStatement stmtItem: stmtItems) {
9026                                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem);
9027                                                        if (resultSetModel != null) {
9028                                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9029                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9030                                                                        
9031                                                                        Transform transform = new Transform();
9032                                                                        transform.setType(Transform.FUNCTION);
9033                                                                        transform.setCode(stmt.getExecuteStmt().getModuleName());
9034                                                                        resultColumn.setTransform(transform);
9035                                                                        
9036                                                                        TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject())
9037                                                                                        .getAliasClause();
9038                                                                        
9039                                                                        if (alias != null && alias.getAliasName() != null) {
9040                                                                                TableColumn tableColumn;
9041                                                                                if (!initColumn) {
9042                                                                                        if (tableModel.isCreateTable()
9043                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9044                                                                                                if(resultColumn.getName().endsWith("*")) {
9045                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9046                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9047                                                                                                                relation.setEffectType(effectType);
9048                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9049                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9050                                                                                                                Process process = modelFactory.createProcess(stmt);
9051                                                                                                                relation.setProcess(process);
9052                                                                                                        }
9053                                                                                                        continue;
9054                                                                                                }
9055                                                                                                else {
9056                                                                                                        if (tableModel.getColumns().size() <= i) {
9057                                                                                                                continue;
9058                                                                                                        }
9059                                                                                                        tableColumn = tableModel.getColumns().get(i);
9060                                                                                                }
9061                                                                                        } else {
9062                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9063                                                                                                                alias.getAliasName());
9064                                                                                        }
9065                                                                                } else {
9066                                                                                        tableColumn = matchColumn(tableColumns, alias.getAliasName());
9067                                                                                        if (tableColumn == null) {
9068                                                                                                continue;
9069                                                                                        }
9070                                                                                }
9071                                        
9072                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9073                                                                                relation.setEffectType(effectType);
9074                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9075                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9076                                                                                Process process = modelFactory.createProcess(stmt);
9077                                                                                relation.setProcess(process);
9078                                                                        } else if (((TResultColumn) resultColumn.getColumnObject())
9079                                                                                        .getFieldAttr() != null) {
9080                                                                                TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
9081                                                                                                .getFieldAttr();
9082                                                                                TableColumn tableColumn;
9083                                                                                if (!initColumn) {
9084                                                                                        if (tableModel.isCreateTable()
9085                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9086                                                                                                if(resultColumn.getName().endsWith("*")) {
9087                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9088                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9089                                                                                                                relation.setEffectType(effectType);
9090                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9091                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9092                                                                                                                Process process = modelFactory.createProcess(stmt);
9093                                                                                                                relation.setProcess(process);
9094                                                                                                        }
9095                                                                                                        continue;
9096                                                                                                }
9097                                                                                                else {
9098                                                                                                        if (tableModel.getColumns().size() <= i) {
9099                                                                                                                continue;
9100                                                                                                        }
9101                                                                                                        tableColumn = tableModel.getColumns().get(i);
9102                                                                                                }
9103                                                                                        } else {
9104                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9105                                                                                                                fieldAttr);
9106                                                                                        }
9107                                                                                } else {
9108                                                                                        tableColumn = matchColumn(tableColumns, fieldAttr);
9109                                                                                        if (tableColumn == null) {
9110                                                                                                continue;
9111                                                                                        }
9112                                                                                }
9113                                                                                
9114                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9115                                                                                relation.setEffectType(effectType);
9116                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9117                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9118                                                                                Process process = modelFactory.createProcess(stmt);
9119                                                                                relation.setProcess(process);
9120                                                                        } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9121                                                                                        .getExpressionType() == EExpressionType.simple_constant_t) {
9122                                                                                if (!initColumn) {
9123                                                                                        TableColumn tableColumn;
9124                                                                                        if (tableModel.isCreateTable()
9125                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9126                                                                                                if(resultColumn.getName().endsWith("*")) {
9127                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9128                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9129                                                                                                                relation.setEffectType(effectType);
9130                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9131                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9132                                                                                                                Process process = modelFactory.createProcess(stmt);
9133                                                                                                                relation.setProcess(process);
9134                                                                                                        }
9135                                                                                                        continue;
9136                                                                                                }
9137                                                                                                else {
9138                                                                                                        if (tableModel.getColumns().size() <= i) {
9139                                                                                                                continue;
9140                                                                                                        }
9141                                                                                                        tableColumn = tableModel.getColumns().get(i);
9142                                                                                                }
9143                                                                                        } else {
9144                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9145                                                                                                                ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9146                                                                                                                                .getConstantOperand(),
9147                                                                                                                i);
9148                                                                                        }
9149                                                                                        
9150                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9151                                                                                        relation.setEffectType(effectType);
9152                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9153                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9154                                                                                        Process process = modelFactory.createProcess(stmt);
9155                                                                                        relation.setProcess(process);
9156                                                                                }
9157                                                                        } else {
9158                                                                                if (!initColumn) {
9159                                                                                        TableColumn tableColumn;
9160                                                                                        if (tableModel.isCreateTable()
9161                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9162                                                                                                if(resultColumn.getName().endsWith("*")) {
9163                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9164                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9165                                                                                                                relation.setEffectType(effectType);
9166                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9167                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9168                                                                                                                Process process = modelFactory.createProcess(stmt);
9169                                                                                                                relation.setProcess(process);
9170                                                                                                        }
9171                                                                                                        continue;
9172                                                                                                }
9173                                                                                                else {
9174                                                                                                        if (tableModel.getColumns().size() <= i) {
9175                                                                                                                continue;
9176                                                                                                        }
9177                                                                                                        tableColumn = tableModel.getColumns().get(i);
9178                                                                                                }
9179                                                                                        } else {
9180                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9181                                                                                                                ((TResultColumn) resultColumn.getColumnObject()).getExpr(),
9182                                                                                                                i);
9183                                                                                        }
9184                                                                                        
9185                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9186                                                                                        relation.setEffectType(effectType);
9187                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9188                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9189                                                                                        Process process = modelFactory.createProcess(stmt);
9190                                                                                        relation.setProcess(process);
9191                                                                                }
9192                                                                        }
9193                                                                }
9194                                                        }
9195                                                }
9196                                        }
9197                                }
9198                                else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) {
9199                                        TObjectName functionName = new TObjectName();
9200                                        functionName.setString(procedure.getProcedureObject().toString());
9201                                        Function function = (Function)createFunction(functionName);
9202                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9203                                        relation.setEffectType(effectType);
9204                                        TObjectName starColumn = new TObjectName();
9205                                        starColumn.setString("*");
9206                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9207                                                        starColumn);
9208                                        tableColumn.setExpandStar(false);
9209                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9210                                        relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
9211                                        Process process = modelFactory.createProcess(stmt);
9212                                        relation.setProcess(process);
9213                                }
9214                        }
9215                }
9216                
9217                if(stmt.getOnDuplicateKeyUpdate()!=null) {
9218                        TTable table = stmt.getTargetTable();
9219                        Table tableModel = modelFactory.createTable(table);
9220                        for(TResultColumn column: stmt.getOnDuplicateKeyUpdate()) {
9221                                if(column.getExpr()==null || column.getExpr().getExpressionType() != EExpressionType.assignment_t) {
9222                                        continue;
9223                                }
9224                                TExpression left = column.getExpr().getLeftOperand();
9225                                TExpression right = column.getExpr().getRightOperand();
9226                                TObjectName columnObject = left.getObjectOperand();
9227                                if (columnObject != null) {
9228                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false);
9229                                        if (tableColumn != null) {
9230                                                columnsInExpr visitor = new columnsInExpr();
9231                                                right.inOrderTraverse(visitor);
9232                                                List<TObjectName> objectNames = visitor.getObjectNames();
9233                                                List<TParseTreeNode> functions = visitor.getFunctions();
9234                                                List<TParseTreeNode> constants = visitor.getConstants();
9235                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9236
9237                                                if (functions != null && !functions.isEmpty()) {
9238                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.update);
9239                                                }
9240                                                if (subquerys != null && !subquerys.isEmpty()) {
9241                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.update);
9242                                                }
9243                                                if (objectNames != null && !objectNames.isEmpty()) {
9244                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.update, functions);
9245                                                }
9246                                                if (constants != null && !constants.isEmpty()) {
9247                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.update, functions);
9248                                                }
9249                                        }
9250                                }
9251                        }
9252                }
9253
9254                if (!expressions.isEmpty() && stmt.getSubQuery() != null) {
9255                        analyzeInsertImpactRelation(stmt.getSubQuery(), tableColumnMap, expressions, effectType);
9256                }
9257        }
9258
9259        private List<TSelectSqlStatement> getLastSelectStmt(TStoredProcedureSqlStatement procedureStmt) {
9260                List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>();
9261                if (procedureStmt.getBodyStatements().size() > 0) {
9262                        for (int j = procedureStmt.getBodyStatements().size() - 1; j >= 0; j--) {
9263                                TCustomSqlStatement stmtItem = procedureStmt.getBodyStatements().get(j);
9264                                if (stmtItem instanceof TSelectSqlStatement) {
9265                                        stmts.add((TSelectSqlStatement) stmtItem);
9266                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9267                                                break;
9268                                        }
9269                                } else if (stmtItem.getStatements() != null) {
9270                                        List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9271                                        if (item != null && !item.isEmpty()) {
9272                                                stmts.addAll(item);
9273                                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9274                                                        break;
9275                                                }
9276                                        }
9277                                }
9278                        }
9279                }
9280                return stmts;
9281        }
9282
9283        private List<TSelectSqlStatement> getLastSelectStmt(TCustomSqlStatement stmt) {
9284                List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>();
9285                for (int j = stmt.getStatements().size() - 1; j >= 0; j--) {
9286                        TCustomSqlStatement stmtItem = stmt.getStatements().get(j);
9287                        if (stmtItem instanceof TSelectSqlStatement) {
9288                                stmts.add((TSelectSqlStatement) stmtItem);
9289                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9290                                        break;
9291                                }
9292                        } else if (stmtItem.getStatements() != null) {
9293                                List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9294                                if (item != null && !item.isEmpty()) {
9295                                        stmts.addAll(item);
9296                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9297                                                break;
9298                                        }
9299                                }
9300                        }
9301                }
9302                return stmts;
9303        }
9304
9305        private TableColumn getStarColumn(List<TableColumn> columns) {
9306                for (TableColumn column : columns) {
9307                        if (column.getName().endsWith("*")) {
9308                                return column;
9309                        }
9310                }
9311                return null;
9312        }
9313
9314        private boolean containStarColumn(List<TableColumn> columns) {
9315                if (columns == null)
9316                        return false;
9317                for (TableColumn column : columns) {
9318                        if (column.getName().endsWith("*")) {
9319                                return true;
9320                        }
9321                }
9322                return false;
9323        }
9324
9325        private boolean containStarColumn(ResultSet resultSet) {
9326                if (resultSet == null || resultSet.getColumns() == null)
9327                        return false;
9328                for (ResultColumn column : resultSet.getColumns()) {
9329                        if (column.getName().endsWith("*")) {
9330                                return true;
9331                        }
9332                }
9333                return false;
9334        }
9335
9336        private int indexOfColumn(List<TResultColumn> columns, TObjectName objectName) {
9337                for (int i = 0; i < columns.size(); i++) {
9338                        if (columns.get(i).toString().trim().equalsIgnoreCase(objectName.toString().trim())) {
9339                                return i;
9340                        }
9341                }
9342                return -1;
9343        }
9344
9345        private boolean isEmptyCollection(Collection<?> keyMap) {
9346                return keyMap == null || keyMap.isEmpty();
9347        }
9348
9349        private void analyzeInsertImpactRelation(TSelectSqlStatement stmt, Map<String, List<TableColumn>> insertMap,
9350                        List<TExpression> expressions, EffectType effectType) {
9351                List<TObjectName> objectNames = new ArrayList<TObjectName>();
9352                for (int i = 0; i < expressions.size(); i++) {
9353                        TExpression condition = expressions.get(i);
9354                        columnsInExpr visitor = new columnsInExpr();
9355                        condition.inOrderTraverse(visitor);
9356                        objectNames.addAll(visitor.getObjectNames());
9357                }
9358
9359                Iterator<String> iter = insertMap.keySet().iterator();
9360                while (iter.hasNext()) {
9361                        String table = iter.next();
9362                        List<TableColumn> tableColumns = insertMap.get(table);
9363                        for (int i = 0; i < tableColumns.size(); i++) {
9364
9365                                TableColumn column = tableColumns.get(i);
9366                                ImpactRelationship relation = modelFactory.createImpactRelation();
9367                                relation.setEffectType(effectType);
9368                                relation.setTarget(new TableColumnRelationshipElement(column));
9369
9370                                for (int j = 0; j < objectNames.size(); j++) {
9371                                        TObjectName columnName = objectNames.get(j);
9372                                        Object model = modelManager.getModel(stmt);
9373                                        if (model instanceof SelectResultSet) {
9374                                                SelectResultSet queryTable = (SelectResultSet) model;
9375                                                List<ResultColumn> columns = queryTable.getColumns();
9376                                                for (int k = 0; k < columns.size(); k++) {
9377                                                        ResultColumn resultColumn = columns.get(k);
9378                                                        if (resultColumn.getAlias() != null
9379                                                                        && columnName.toString().equalsIgnoreCase(resultColumn.getAlias())) {
9380                                                                relation.addSource(
9381                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
9382                                                        } else if (resultColumn.getName() != null
9383                                                                        && columnName.toString().equalsIgnoreCase(resultColumn.getName())) {
9384                                                                relation.addSource(
9385                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
9386                                                        }
9387                                                }
9388                                        }
9389                                }
9390                        }
9391                }
9392        }
9393
9394        private void analyzeUpdateStmt(TUpdateSqlStatement stmt) {
9395                if (stmt.getResultColumnList() == null)
9396                        return;
9397
9398                TTable table = stmt.getTargetTable();
9399                while (table.getCTE() != null || table.getSubquery() != null || (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null)) {
9400                        if (table.getCTE() != null) {
9401                                table = table.getCTE().getSubquery().getTables().getTable(0);
9402                        } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) {
9403                                table = table.getLinkTable().getSubquery().getTables().getTable(0);
9404                        } else if (table.getSubquery() != null) {
9405                                table = table.getSubquery().getTables().getTable(0);
9406                        }
9407                }
9408                Table tableModel = modelFactory.createTable(table);
9409                Process process = modelFactory.createProcess(stmt);
9410                tableModel.addProcess(process);
9411
9412                for (int i = 0; i < stmt.tables.size(); i++) {
9413                        TTable tableElement = stmt.tables.getTable(i);
9414                        if (tableElement.getSubquery() != null) {
9415                                QueryTable queryTable = modelFactory.createQueryTable(tableElement);
9416                                TSelectSqlStatement subquery = tableElement.getSubquery();
9417                                analyzeSelectStmt(subquery);
9418
9419                                if (subquery.getSetOperatorType() != ESetOperatorType.none) {
9420                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager.getModel(subquery);
9421                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
9422                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
9423                                                ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
9424                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
9425                                                selectSetRalation.setEffectType(EffectType.select);
9426                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
9427                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
9428                                                selectSetRalation.setProcess(process);
9429                                        }
9430                                }
9431
9432                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(tableElement.getSubquery());
9433                                if (resultSetModel != null && resultSetModel != queryTable
9434                                                && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
9435                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9436                                        impactRelation.setEffectType(EffectType.update);
9437                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9438                                                        resultSetModel.getRelationRows()));
9439                                        impactRelation.setTarget(
9440                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(queryTable.getRelationRows()));
9441                                }
9442
9443                        } else if (tableElement.getCTE() != null) {
9444                                QueryTable queryTable = modelFactory.createQueryTable(tableElement);
9445
9446                                TObjectNameList cteColumns = tableElement.getCTE().getColumnList();
9447                                if (cteColumns != null) {
9448                                        for (int j = 0; j < cteColumns.size(); j++) {
9449                                                modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
9450                                        }
9451                                }
9452                                TSelectSqlStatement subquery = tableElement.getCTE().getSubquery();
9453                                if (subquery != null && !stmtStack.contains(subquery)) {
9454                                        analyzeSelectStmt(subquery);
9455
9456                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
9457                                        if (resultSetModel != null && resultSetModel != queryTable
9458                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
9459                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9460                                                impactRelation.setEffectType(EffectType.select);
9461                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9462                                                                resultSetModel.getRelationRows()));
9463                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9464                                                                queryTable.getRelationRows()));
9465                                        }
9466
9467                                        if (subquery.getSetOperatorType() != ESetOperatorType.none) {
9468                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
9469                                                                .getModel(subquery);
9470                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
9471                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
9472                                                        ResultColumn targetColumn = null;
9473                                                        if (cteColumns != null) {
9474                                                                targetColumn = queryTable.getColumns().get(j);
9475                                                        } else {
9476                                                                targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
9477                                                        }
9478                                                        for (Set<TObjectName> starLinkColumns : sourceColumn.getStarLinkColumns().values()) {
9479                                                                for (TObjectName starLinkColumn : starLinkColumns) {
9480                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
9481                                                                }
9482                                                        }
9483                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
9484                                                        selectSetRalation.setEffectType(EffectType.select);
9485                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
9486                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
9487                                                        selectSetRalation.setProcess(process);
9488                                                }
9489                                        } else {
9490                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
9491                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
9492                                                        ResultColumn targetColumn = null;
9493                                                        if (cteColumns != null) {
9494                                                                targetColumn = queryTable.getColumns().get(j);
9495                                                        } else {
9496                                                                targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
9497                                                        }
9498                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
9499                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
9500                                                        }
9501                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
9502                                                        selectSetRalation.setEffectType(EffectType.select);
9503                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
9504                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
9505                                                        selectSetRalation.setProcess(process);
9506                                                }
9507                                        }
9508                                } else if (tableElement.getCTE().getUpdateStmt() != null) {
9509                                        analyzeCustomSqlStmt(tableElement.getCTE().getUpdateStmt());
9510                                } else if (tableElement.getCTE().getInsertStmt() != null) {
9511                                        analyzeCustomSqlStmt(tableElement.getCTE().getInsertStmt());
9512                                } else if (tableElement.getCTE().getDeleteStmt() != null) {
9513                                        analyzeCustomSqlStmt(tableElement.getCTE().getDeleteStmt());
9514                                }
9515                        } else {
9516                                modelFactory.createTable(stmt.tables.getTable(i));
9517                        }
9518                }
9519
9520                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
9521                        TResultColumn field = stmt.getResultColumnList().getResultColumn(i);
9522
9523                        if (field.getExpr().getExpressionType() == EExpressionType.function_t) {
9524                                continue;
9525                        }
9526
9527                        TExpression expression = field.getExpr().getLeftOperand();
9528                        if (expression == null) {
9529                                ErrorInfo errorInfo = new ErrorInfo();
9530                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
9531                                errorInfo.setErrorMessage(
9532                                                "Can't get result column expression. Expression is " + field.getExpr().toString());
9533                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(field.getExpr().getStartToken().lineNo,
9534                                                field.getExpr().getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
9535                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(field.getExpr().getEndToken().lineNo,
9536                                                field.getExpr().getEndToken().columnNo + field.getExpr().getEndToken().astext.length(),
9537                                                ModelBindingManager.getGlobalHash()));
9538                                errorInfo.fillInfo(this);
9539                                errorInfos.add(errorInfo);
9540                                continue;
9541                        }
9542                        if (expression.getExpressionType() == EExpressionType.list_t) {
9543                                TExpression setExpression = field.getExpr().getRightOperand();
9544                                if (setExpression != null && setExpression.getSubQuery() != null) {
9545                                        TSelectSqlStatement query = setExpression.getSubQuery();
9546                                        analyzeSelectStmt(query);
9547
9548                                        SelectResultSet resultSetModel = (SelectResultSet) modelManager
9549                                                        .getModel(query.getResultColumnList());
9550
9551                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
9552                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9553                                                impactRelation.setEffectType(EffectType.update);
9554                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9555                                                                resultSetModel.getRelationRows()));
9556                                                impactRelation.setTarget(
9557                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
9558                                        }
9559
9560                                        TExpressionList columnList = expression.getExprList();
9561                                        for (int j = 0; j < columnList.size(); j++) {
9562                                                TObjectName column = columnList.getExpression(j).getObjectOperand();
9563
9564                                                if (column.getDbObjectType() == EDbObjectType.variable) {
9565                                                        continue;
9566                                                }
9567
9568                                                if (column.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql
9569                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
9570                                                        continue;
9571                                                }
9572
9573                                                if (column.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana
9574                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
9575                                                        continue;
9576                                                }
9577
9578                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
9579                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false);
9580                                                if (tableColumn != null) {
9581                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9582                                                        relation.setEffectType(EffectType.update);
9583                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9584                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9585                                                        relation.setProcess(process);
9586                                                }
9587
9588                                        }
9589                                }
9590                        } else if (expression.getExpressionType() == EExpressionType.simple_object_name_t) {
9591                                TExpression setExpression = field.getExpr().getRightOperand();
9592                                if (setExpression != null && setExpression.getSubQuery() != null) {
9593                                        TSelectSqlStatement query = setExpression.getSubQuery();
9594                                        analyzeSelectStmt(query);
9595
9596                                        SelectResultSet resultSetModel = (SelectResultSet) modelManager
9597                                                        .getModel(query.getResultColumnList());
9598
9599                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
9600                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9601                                                impactRelation.setEffectType(EffectType.update);
9602                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9603                                                                resultSetModel.getRelationRows()));
9604                                                impactRelation.setTarget(
9605                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
9606                                        }
9607
9608                                        TObjectName column = expression.getObjectOperand();
9609                                        ResultColumn resultColumn = resultSetModel.getColumns().get(0);
9610                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false);
9611                                        if (tableColumn != null) {
9612                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9613                                                relation.setEffectType(EffectType.update);
9614                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9615                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9616                                                relation.setProcess(process);
9617                                        }
9618                                } else if (setExpression != null) {
9619                                        // ResultSet resultSet = modelFactory.createResultSet(stmt,
9620                                        // true);
9621
9622                                        ResultSet resultSet = modelFactory.createResultSet(stmt, false);
9623
9624                                        createPseudoImpactRelation(stmt, resultSet, EffectType.update);
9625
9626                                        TObjectName columnObject = expression.getObjectOperand();
9627
9628                                        ResultColumn updateColumn = modelFactory.createUpdateResultColumn(resultSet, columnObject);
9629
9630                                        columnsInExpr visitor = new columnsInExpr();
9631                                        field.getExpr().getRightOperand().inOrderTraverse(visitor);
9632
9633                                        List<TObjectName> objectNames = visitor.getObjectNames();
9634                                        List<TParseTreeNode> functions = visitor.getFunctions();
9635                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9636
9637                                        if (functions != null && !functions.isEmpty()) {
9638                                                analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.update);
9639                                        }
9640
9641                                        if (subquerys != null && !subquerys.isEmpty()) {
9642                                                analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.update);
9643                                        }
9644
9645                                        Transform transform = new Transform();
9646                                        transform.setType(Transform.EXPRESSION);
9647                                        transform.setCode(setExpression);
9648                                        updateColumn.setTransform(transform);
9649                                        analyzeDataFlowRelation(updateColumn, objectNames, EffectType.update, functions);
9650
9651                                        List<TParseTreeNode> constants = visitor.getConstants();
9652                                        analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.update, functions);
9653
9654                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false);
9655                                        if(tableColumn!=null) {
9656                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9657                                                relation.setEffectType(EffectType.update);
9658                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9659                                                relation.addSource(new ResultColumnRelationshipElement(updateColumn));
9660                                                relation.setProcess(process);
9661                                        }
9662                                        
9663                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9664                                        impactRelation.setEffectType(EffectType.update);
9665                                        impactRelation.addSource(
9666                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
9667                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
9668                                                        tableModel.getRelationRows()));
9669                                }
9670                        }
9671                }
9672
9673                if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
9674                        for (int i = 0; i < stmt.getJoins().size(); i++) {
9675                                TJoin join = stmt.getJoins().getJoin(i);
9676                                if (join.getJoinItems() != null) {
9677                                        for (int j = 0; j < join.getJoinItems().size(); j++) {
9678                                                TJoinItem joinItem = join.getJoinItems().getJoinItem(j);
9679                                                TExpression expr = joinItem.getOnCondition();
9680                                                analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on,
9681                                                                EffectType.update);
9682                                        }
9683                                }
9684                        }
9685                }
9686
9687                if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) {
9688                        analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where,
9689                                        EffectType.update);
9690                }
9691
9692                if (stmt.getOutputClause() != null) {
9693                        TOutputClause outputClause = stmt.getOutputClause();
9694                        if (outputClause.getSelectItemList() != null) {
9695                                ResultSet resultSet = modelFactory.createResultSet(outputClause, false);
9696                                for (int j = 0; j < outputClause.getSelectItemList().size(); j++) {
9697                                        TResultColumn sourceColumn = outputClause.getSelectItemList().getResultColumn(j);
9698                                        ResultColumn sourceColumnModel = modelFactory.createResultColumn(resultSet, sourceColumn);
9699                                        analyzeResultColumn(sourceColumn, EffectType.select);
9700
9701                                        if (outputClause.getIntoTable() != null) {
9702                                                Table intoTableModel = modelFactory.createTableByName(outputClause.getIntoTable());
9703                                                intoTableModel.addProcess(process);
9704                                                if (outputClause.getIntoColumnList() != null) {
9705                                                        TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel,
9706                                                                        outputClause.getIntoColumnList().getObjectName(j));
9707
9708                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9709                                                        relation.setEffectType(EffectType.insert);
9710                                                        relation.setTarget(new TableColumnRelationshipElement(intoTableColumn));
9711                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel));
9712                                                } else if (sourceColumn.getAliasClause() != null
9713                                                                || sourceColumn.getExpr().getObjectOperand() != null) {
9714                                                        TObjectName tableColumnObject = null;
9715                                                        if (sourceColumn.getAliasClause() != null) {
9716                                                                tableColumnObject = sourceColumn.getAliasClause().getAliasName();
9717                                                        } else {
9718                                                                tableColumnObject = sourceColumn.getExpr().getObjectOperand();
9719                                                        }
9720
9721                                                        TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel,
9722                                                                        tableColumnObject);
9723                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9724                                                        relation.setEffectType(EffectType.insert);
9725                                                        relation.setTarget(new TableColumnRelationshipElement(intoTableColumn));
9726                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel));
9727                                                }
9728                                        }
9729                                }
9730                        }
9731                }
9732        }
9733
9734        private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants,
9735                        EffectType effectType, List<TParseTreeNode> functions) {
9736                analyzeConstantDataFlowRelation(modelObject, constants, effectType, functions, null);
9737        }
9738
9739        private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants,
9740                        EffectType effectType, List<TParseTreeNode> functions, Process process) {
9741                if (constants == null || constants.size() == 0)
9742                        return;
9743
9744                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9745                relation.setEffectType(effectType);
9746                relation.setProcess(process);
9747
9748                if (functions != null && !functions.isEmpty()) {
9749                        relation.setFunction(getFunctionName(functions.get(0)));
9750                }
9751
9752                if (modelObject instanceof ResultColumn) {
9753                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
9754
9755                } else if (modelObject instanceof TableColumn) {
9756                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
9757
9758                } else {
9759                        throw new UnsupportedOperationException();
9760                }
9761
9762                if (option.isShowConstantTable()) {
9763                        Table constantTable = null;
9764                        if(modelObject instanceof FunctionResultColumn && ((FunctionResultColumn)modelObject).getFunction() instanceof TFunctionCall) {
9765                                TFunctionCall function = (TFunctionCall)((FunctionResultColumn)modelObject).getFunction();
9766                                if(function.getFunctionType() == EFunctionType.struct_t) {
9767                                        constantTable = modelFactory.createConstantsTable(String.valueOf(function.toString().hashCode()));
9768                                }
9769                        }
9770                        if(constantTable == null) {
9771                                constantTable = modelFactory.createConstantsTable(stmtStack.peek());
9772                        }
9773                        for (int i = 0; i < constants.size(); i++) {
9774                                TParseTreeNode constant = constants.get(i);
9775                                if (constant instanceof TConstant) {
9776                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TConstant) constant);
9777                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
9778                                } else if (constant instanceof TObjectName) {
9779                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TObjectName) constant,
9780                                                        false);
9781                                        if(constantColumn == null) {
9782                                                continue;
9783                                        }
9784                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
9785                                }
9786                        }
9787                }
9788
9789        }
9790
9791        private String getFunctionName(TParseTreeNode parseTreeNode) {
9792                if (parseTreeNode instanceof TFunctionCall) {
9793                        return ((TFunctionCall) parseTreeNode).getFunctionName().toString();
9794                }
9795                if (parseTreeNode instanceof TCaseExpression) {
9796                        return "case-when";
9797                }
9798                return null;
9799        }
9800
9801        private void analyzeCreateViewStmt(TCustomSqlStatement stmt, TSelectSqlStatement subquery,
9802                        TViewAliasClause viewAlias, TObjectName viewName) {
9803
9804                if (subquery != null) {
9805                        TTableList tables = subquery.getTables();
9806                        if (tables != null) {
9807                                for (int i = 0; i < tables.size(); i++) {
9808                                        TTable table = tables.getTable(i);
9809                                        TCustomSqlStatement createView = viewDDLMap
9810                                                        .get(DlineageUtil.getTableFullName(table.getTableName().toString()));
9811                                        if (createView != null) {
9812                                                analyzeCustomSqlStmt(createView);
9813                                        }
9814                                }
9815                        }
9816                        analyzeSelectStmt(subquery);
9817                }
9818
9819        
9820                if (viewAlias != null && viewAlias.getViewAliasItemList() != null) {
9821                        TViewAliasItemList viewItems = viewAlias.getViewAliasItemList();
9822                        Table viewModel = modelFactory.createView(stmt, viewName, true);
9823                        viewModel.setFromDDL(true);
9824                        viewModel.setDetermined(true);
9825                        Process process = modelFactory.createProcess(stmt);
9826                        viewModel.addProcess(process);
9827                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
9828                        if (resultSetModel != null) {
9829                                int resultSetSize = resultSetModel.getColumns().size();
9830                                int viewItemSize = viewItems.size();
9831                                int j = 0;
9832                                int viewColumnSize = viewItemSize;
9833                                if (resultSetModel.isDetermined() && resultSetSize > viewColumnSize) {
9834                                        viewColumnSize = resultSetSize;
9835                                }
9836                                for (int i = 0; i < viewColumnSize && j < resultSetSize; i++) {
9837                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);                                 
9838                                        if (i < viewItemSize) {
9839                                                TObjectName alias = viewItems.getViewAliasItem(i).getAlias();
9840
9841                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
9842                                                        j++;
9843                                                } else {
9844                                                        if (resultSetSize - j == viewItems.size() - i) {
9845                                                                j++;
9846                                                        }
9847                                                }
9848
9849                                                if (alias != null) {
9850                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true);
9851                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
9852                                                        if (resultColumn != null) {
9853                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9854                                                                relation.setEffectType(EffectType.create_view);
9855                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
9856                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9857                                                                relation.setProcess(process);
9858                                                        }
9859                                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
9860                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
9861                                                                        (TObjectName) resultColumn.getColumnObject(), i, true);
9862                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
9863                                                        if (resultColumn != null) {
9864                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9865                                                                relation.setEffectType(EffectType.create_view);
9866                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
9867                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9868                                                                relation.setProcess(process);
9869                                                        }
9870                                                } else if (resultColumn.getColumnObject() instanceof TResultColumn) {
9871                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
9872                                                                        ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), i, true);
9873                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
9874                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
9875                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
9876                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
9877                                                        }
9878                                                        if (resultColumn != null) {
9879                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9880                                                                relation.setEffectType(EffectType.create_view);
9881                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
9882                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9883                                                                relation.setProcess(process);
9884                                                        }
9885                                                }
9886                                        }
9887                                        else if(resultSetModel.isDetermined()){
9888                                                TObjectName viewColumnName = new TObjectName();
9889                                                viewColumnName.setString(resultColumn.getName());
9890                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, viewModel.getColumns().size(), true);
9891                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9892                                                relation.setEffectType(EffectType.create_view);
9893                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
9894                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9895                                                relation.setProcess(process);
9896                                                j++;
9897                                        }
9898                                }
9899                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
9900                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9901                                        impactRelation.setEffectType(EffectType.create_view);
9902                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9903                                                        resultSetModel.getRelationRows()));
9904                                        impactRelation.setTarget(
9905                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
9906                                }
9907                        }
9908
9909                        if (subquery.getResultColumnList() == null && subquery.getValueClause() != null
9910                                        && subquery.getValueClause().getValueRows().size() == viewItems.size()) {
9911                                for (int i = 0; i < viewItems.size(); i++) {
9912                                        TObjectName alias = viewItems.getViewAliasItem(i).getAlias();
9913
9914                                        if (alias != null) {
9915                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true);
9916                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
9917                                                TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr();
9918
9919                                                columnsInExpr visitor = new columnsInExpr();
9920                                                expression.inOrderTraverse(visitor);
9921                                                List<TObjectName> objectNames = visitor.getObjectNames();
9922                                                List<TParseTreeNode> functions = visitor.getFunctions();
9923
9924                                                if (functions != null && !functions.isEmpty()) {
9925                                                        analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select);
9926
9927                                                }
9928
9929                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9930                                                if (subquerys != null && !subquerys.isEmpty()) {
9931                                                        analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select);
9932                                                }
9933
9934                                                analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions);
9935                                                List<TParseTreeNode> constants = visitor.getConstants();
9936                                                analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions);
9937                                        }
9938                                }
9939                        }
9940
9941                } else {
9942                        if (viewName == null) {
9943                                ErrorInfo errorInfo = new ErrorInfo();
9944                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
9945                                errorInfo.setErrorMessage("Can't get view name. CreateView is " + stmt.toString());
9946                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
9947                                                stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
9948                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
9949                                                stmt.getEndToken().columnNo + stmt.getEndToken().astext.length(),
9950                                                ModelBindingManager.getGlobalHash()));
9951                                errorInfo.fillInfo(this);
9952                                errorInfos.add(errorInfo);
9953                                return;
9954                        }
9955                        Table viewModel = modelFactory.createView(stmt, viewName);
9956                        Process process = modelFactory.createProcess(stmt);
9957                        viewModel.addProcess(process);
9958                        if (subquery != null && !subquery.isCombinedQuery()) {
9959                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
9960                                                .getModel(subquery.getResultColumnList());
9961
9962                                boolean determined = false;
9963                                if (!containStarColumn(resultSetModel)) {
9964                                        viewModel.setCreateTable(true);
9965                                        determined = true;
9966                                        viewModel.setFromDDL(true);
9967                                }
9968                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9969                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9970                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
9971                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
9972
9973                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
9974                                                if (alias != null && alias.getAliasName() != null) {
9975                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i,
9976                                                                        determined);
9977                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9978                                                        relation.setEffectType(EffectType.create_view);
9979                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
9980                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9981                                                        relation.setProcess(process);
9982                                                        if (determined) {
9983                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
9984                                                        }
9985                                                } else if (columnObject.getFieldAttr() != null) {
9986                                                        TObjectName viewColumnObject = columnObject.getFieldAttr();
9987                                                        TableColumn viewColumn;
9988                                                        Object model = modelManager.getModel(resultColumn.getColumnObject());
9989                                                        if ("*".equals(viewColumnObject.getColumnNameOnly())) {
9990                                                                if (model instanceof LinkedHashMap) {
9991                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
9992                                                                        LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model;
9993                                                                        if ("*".equals(columnName)) {
9994                                                                                for (String key : resultColumns.keySet()) {
9995                                                                                        ResultColumn column = resultColumns.get(key);
9996                                                                                        viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName());
9997                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9998                                                                                        relation.setEffectType(EffectType.create_view);
9999                                                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10000                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
10001                                                                                        relation.setProcess(process);
10002                                                                                }
10003                                                                                continue;
10004                                                                        } else if (resultColumns.containsKey(columnName)) {
10005                                                                                ResultColumn column = resultColumns.get(columnName);
10006                                                                                viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName());
10007                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10008                                                                                relation.setEffectType(EffectType.create_view);
10009                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10010                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
10011                                                                                relation.setProcess(process);
10012                                                                                continue;
10013                                                                        }
10014                                                                }
10015                                                        }
10016                                                        
10017                                                        if (!SQLUtil.isEmpty(viewColumnObject.getColumnNameOnly())
10018                                                                        && viewColumnObject.getPropertyToken() != null) {
10019                                                                TObjectName object = new TObjectName();
10020                                                                // object.setString(viewColumnObject.getPropertyToken().astext);
10021                                                                object.setPartToken(viewColumnObject.getPropertyToken());
10022                                                                object.setStartToken(viewColumnObject.getPropertyToken());
10023                                                                object.setEndToken(viewColumnObject.getPropertyToken());
10024                                                                viewColumn = modelFactory.createViewColumn(viewModel, object, i, determined);
10025                                                        } else {
10026                                                                viewColumn = modelFactory.createViewColumn(viewModel, columnObject.getFieldAttr(),
10027                                                                                i, determined);
10028                                                        }
10029                                                        
10030                                                        if(determined) {
10031                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10032                                                        }
10033                                                        
10034                                                        if (model instanceof ResultColumn) {
10035                                                                ResultColumn column = (ResultColumn) modelManager
10036                                                                                .getModel(resultColumn.getColumnObject());
10037                                                                if (column != null && !column.getStarLinkColumns().isEmpty()) {
10038                                                                        viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
10039                                                                }
10040                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10041                                                                relation.setEffectType(EffectType.create_view);
10042                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10043                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10044                                                                if (sqlenv == null) {
10045                                                                        if (resultColumn.isShowStar()) {
10046                                                                                relation.setShowStarRelation(true);
10047                                                                                viewColumn.setShowStar(true);
10048                                                                                resultColumn.setShowStar(true);
10049                                                                                setSourceShowStar(resultColumn);
10050                                                                        }
10051                                                                }
10052                                                                if (viewColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
10053                                                                        viewModel.setStarStmt("create_view");
10054                                                                }
10055                                                                relation.setProcess(process);
10056                                                        }
10057                                                } else if (resultColumn.getAlias() != null && columnObject.getExpr()
10058                                                                .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
10059                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10060                                                                        columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined);
10061                                                        if(determined) {
10062                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10063                                                        }
10064                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10065                                                        relation.setEffectType(EffectType.create_view);
10066                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10067                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10068                                                        relation.setProcess(process);
10069                                                } else {
10070                                                        TGSqlParser parser = columnObject.getGsqlparser();
10071                                                        TObjectName viewColumnName = parser
10072                                                                        .parseObjectName(generateQuotedName(parser, columnObject.toString()));
10073                                                        if (viewColumnName == null) {
10074                                                                ErrorInfo errorInfo = new ErrorInfo();
10075                                                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
10076                                                                errorInfo.setErrorMessage(
10077                                                                                "Can't parse view column. Column is " + columnObject.toString());
10078                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(
10079                                                                                columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo,
10080                                                                                ModelBindingManager.getGlobalHash()));
10081                                                                errorInfo
10082                                                                                .setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo,
10083                                                                                                columnObject.getEndToken().columnNo
10084                                                                                                                + columnObject.getEndToken().astext.length(),
10085                                                                                                ModelBindingManager.getGlobalHash()));
10086                                                                errorInfo.fillInfo(this);
10087                                                                errorInfos.add(errorInfo);
10088                                                        } else {
10089                                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i,
10090                                                                                determined);
10091                                                                if(determined) {
10092                                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10093                                                                }
10094                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10095                                                                relation.setEffectType(EffectType.create_view);
10096                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10097                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10098                                                                relation.setProcess(process);
10099                                                        }
10100                                                }
10101                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
10102                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10103                                                                (TObjectName) resultColumn.getColumnObject(), i, determined);
10104                                                if(determined) {
10105                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10106                                                }
10107                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10108                                                relation.setEffectType(EffectType.create_view);
10109                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10110                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10111                                                relation.setProcess(process);
10112                                        }
10113                                }
10114                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10115                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10116                                        impactRelation.setEffectType(EffectType.create_view);
10117                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10118                                                        resultSetModel.getRelationRows()));
10119                                        impactRelation.setTarget(
10120                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
10121                                }
10122                        } else if (subquery != null && subquery.isCombinedQuery()) {
10123                                SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(subquery);
10124
10125                                boolean determined = false;
10126                                if (!containStarColumn(resultSetModel)) {
10127                                        viewModel.setCreateTable(true);
10128                                        viewModel.setFromDDL(true);
10129                                        determined = true;
10130                                }
10131
10132                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
10133                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
10134
10135                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
10136                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
10137
10138                                                TAliasClause alias = columnObject.getAliasClause();
10139                                                if (alias != null && alias.getAliasName() != null) {
10140                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i,
10141                                                                        determined);
10142                                                        if(determined) {
10143                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10144                                                        }
10145                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10146                                                        relation.setEffectType(EffectType.create_view);
10147                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10148                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10149                                                        relation.setProcess(process);
10150                                                } else if (columnObject.getFieldAttr() != null) {
10151                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10152                                                                        columnObject.getFieldAttr(), i, determined);
10153                                                        if(determined) {
10154                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10155                                                        }
10156                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
10157                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
10158                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
10159                                                        }
10160                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10161                                                        relation.setEffectType(EffectType.create_view);
10162                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10163                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10164                                                        relation.setProcess(process);
10165                                                } else if (resultColumn.getAlias() != null && columnObject.getExpr()
10166                                                                .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
10167                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10168                                                                        columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined);
10169                                                        if(determined) {
10170                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10171                                                        }
10172                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10173                                                        relation.setEffectType(EffectType.create_view);
10174                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10175                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10176                                                        relation.setProcess(process);
10177                                                } else {
10178                                                        TGSqlParser parser = columnObject.getGsqlparser();
10179                                                        TObjectName viewColumnName = parser
10180                                                                        .parseObjectName(generateQuotedName(parser, columnObject.toString()));
10181                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i,
10182                                                                        determined);
10183                                                        if(determined) {
10184                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10185                                                        }
10186                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10187                                                        relation.setEffectType(EffectType.create_view);
10188                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10189                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10190                                                        relation.setProcess(process);
10191                                                }
10192                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
10193                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10194                                                                (TObjectName) resultColumn.getColumnObject(), i, determined);
10195                                                if(viewColumn!=null) {
10196                                                        if(determined) {
10197                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10198                                                        }
10199                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10200                                                        relation.setEffectType(EffectType.create_view);
10201                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10202                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10203                                                        relation.setProcess(process);
10204                                                }
10205                                        }
10206                                }
10207                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10208                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10209                                        impactRelation.setEffectType(EffectType.create_view);
10210                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10211                                                        resultSetModel.getRelationRows()));
10212                                        impactRelation.setTarget(
10213                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
10214                                }
10215                        }
10216                }
10217        }
10218
10219        private void setSourceShowStar(Object resultColumn) {
10220                for (Relationship relation : modelManager.getRelations()) {
10221                        Collection<RelationshipElement<?>> sources = (Collection<RelationshipElement<?>>)relation.getSources();
10222                        if (relation.getTarget().getElement() == resultColumn && sources != null) {
10223
10224                                ((AbstractRelationship) relation).setShowStarRelation(true);
10225                                for (RelationshipElement<?> source : sources) {
10226                                        Object column = source.getElement();
10227                                        if (column instanceof TableColumn) {
10228                                                if (((TableColumn) column).isShowStar())
10229                                                        continue;
10230                                                ((TableColumn) column).setShowStar(true);
10231                                        }
10232                                        if (column instanceof ResultColumn) {
10233                                                if (((ResultColumn) column).isShowStar())
10234                                                        continue;
10235                                                ((ResultColumn) column).setShowStar(true);
10236                                        }
10237                                        setSourceShowStar(column);
10238                                }
10239                        }
10240                }
10241        }
10242
10243        private String generateQuotedName(TGSqlParser parser, String name) {
10244                return "\"" + name + "\"";
10245        }
10246
10247        private void appendRelations(dataflow dataflow) {
10248                Relationship[] relations = modelManager.getRelations();
10249
10250                appendRelation(dataflow, relations, DataFlowRelationship.class);
10251                appendRelation(dataflow, relations, IndirectImpactRelationship.class);
10252                appendRecordSetRelation(dataflow, relations);
10253                appendCallRelation(dataflow, relations);
10254                appendRelation(dataflow, relations, ImpactRelationship.class);
10255                appendRelation(dataflow, relations, JoinRelationship.class);
10256                appendRelation(dataflow, relations, ERRelationship.class);
10257                appendRelation(dataflow, relations, CrudRelationship.class);
10258        }
10259
10260        private Set<String> appendStarColumns = new HashSet<String>();
10261        private void appendRelation(dataflow dataflow, Relationship[] relations, Class<? extends Relationship> clazz) {
10262                for (int i = 0; i < relations.length; i++) {
10263                        AbstractRelationship relation = (AbstractRelationship) relations[i];
10264                        if (relation.getClass() == clazz) {
10265                                if (relation.getSources() == null || relation.getTarget() == null) {
10266                                        continue;
10267                                }
10268                                Object targetElement = relation.getTarget().getElement();
10269                                TObjectName targetColumnName = null;
10270                                if(relation.getTarget() instanceof ResultColumnRelationshipElement) {
10271                                        targetColumnName = ((ResultColumnRelationshipElement) relation.getTarget()).getColumnName();
10272                                }
10273                                if (targetElement instanceof ResultColumn) {
10274                                        ResultColumn targetColumn = (ResultColumn) targetElement;
10275                                        if (!targetColumn.isPseduo()) 
10276                                        {
10277                                                if (targetColumnName == null) 
10278                                                {
10279                                                        if ("*".equals(targetColumn.getName())) {
10280                                                                updateResultColumnStarLinks(dataflow, relation, -1);
10281                                                        }
10282
10283                                                        if (targetColumn.hasStarLinkColumn()) {
10284                                                                for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) {
10285                                                                        appendStarRelation(dataflow, relation, j);
10286                                                                }
10287
10288                                                                if (!containsStar(relation.getSources())) {
10289                                                                        continue;
10290                                                                }
10291                                                        }
10292                                                }
10293                                                else {
10294                                                        String columnName = DlineageUtil.getColumnName(targetColumnName);
10295                                                        int index = targetColumn.getStarLinkColumnNames().indexOf(columnName);
10296                                                        if (index != -1) {
10297                                                                int size = targetColumn.getStarLinkColumnNames().size();
10298                                                                if ("*".equals(targetColumn.getName())) {
10299                                                                        if (appendStarColumns.contains(columnName)) {
10300                                                                                updateResultColumnStarLinks(dataflow, relation, index);
10301                                                                        }
10302                                                                        else {
10303                                                                                updateResultColumnStarLinks(dataflow, relation, -1);
10304                                                                                appendStarColumns.add(columnName);
10305                                                                        }
10306                                                                }
10307                                                                appendStarRelation(dataflow, relation, index);
10308                                                                for(int j= size; j < targetColumn.getStarLinkColumnNames().size(); j++) {
10309                                                                        appendStarRelation(dataflow, relation, j);
10310                                                                }
10311                                                                if (!containsStar(relation.getSources())) {
10312                                                                        continue;
10313                                                                }
10314                                                        }
10315                                                }
10316                                        }
10317                                } else if (targetElement instanceof TableColumn) {
10318                                        TableColumn targetColumn = (TableColumn) targetElement;
10319                                        if (!targetColumn.isPseduo()) {
10320                                                if ("*".equals(targetColumn.getName())) {
10321                                                        updateTableColumnStarLinks(dataflow, relation);
10322                                                }
10323
10324                                                if (targetColumn.hasStarLinkColumn() && !targetColumn.isVariant()
10325                                                                && targetColumn.isExpandStar()) {
10326                                                        for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) {
10327                                                                appendStarRelation(dataflow, relation, j);
10328                                                        }
10329                                                        if (!containsStar(relation.getSources())) {
10330                                                                continue;
10331                                                        }
10332                                                }
10333                                        }
10334                                }
10335
10336                                relationship relationElement = new relationship();
10337                                relationElement.setType(relation.getRelationshipType().name());
10338                                if (relation.getEffectType() != null) {
10339                                        relationElement.setEffectType(relation.getEffectType().name());
10340                                }
10341                                if (relation.getFunction() != null) {
10342                                        relationElement.setFunction(relation.getFunction());
10343                                }
10344                                relationElement.setSqlHash(relation.getSqlHash());
10345                                relationElement.setSqlComment(relation.getSqlComment());
10346
10347                                if (relation.getProcedureId() != null) {
10348                                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
10349                                }
10350                                relationElement.setId(String.valueOf(relation.getId()));
10351                                if (relation.getProcess() != null) {
10352                                        relationElement.setProcessId(String.valueOf(relation.getProcess().getId()));
10353                                        if (relation.getProcess().getGspObject() != null) {
10354                                                relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name());
10355                                        }
10356                                }
10357
10358                                if (relation.getPartition() != null) {
10359                                        relationElement.setPartition(relation.getPartition());
10360                                }
10361                                relationElement.setSqlHash(relation.getSqlHash());
10362                                relationElement.setSqlComment(relation.getSqlComment());
10363                                
10364                                if (relation.getProcedureId() != null) {
10365                                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
10366                                }
10367                                
10368                                if (relation instanceof JoinRelationship) {
10369                                        relationElement.setCondition(((JoinRelationship) relation).getJoinCondition());
10370                                        relationElement.setJoinType(((JoinRelationship) relation).getJoinType().name());
10371                                        relationElement.setClause(((JoinRelationship) relation).getJoinClauseType().name());
10372                                }
10373
10374                                if(relation instanceof ImpactRelationship){
10375                                        ImpactRelationship impactRelationship = (ImpactRelationship)relation;
10376                                        if(impactRelationship.getJoinClauseType()!=null){
10377                                                relationElement.setClause(impactRelationship.getJoinClauseType().name());
10378                                        }
10379                                }
10380
10381                                String targetName = null;
10382                                Object columnObject = null;
10383                                List<TObjectName> targetObjectNames = null;
10384
10385                                if (targetElement instanceof ResultSetRelationRows) {
10386                                        ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement;
10387                                        targetColumn target = new targetColumn();
10388                                        target.setId(String.valueOf(targetColumn.getId()));
10389                                        target.setColumn(targetColumn.getName());
10390                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
10391                                        target.setParent_name(getResultSetName(targetColumn.getHolder()));
10392                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
10393                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
10394                                                                + convertCoordinate(targetColumn.getEndPosition()));
10395                                        }
10396                                        if (relation instanceof RecordSetRelationship) {
10397                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
10398                                        }
10399                                        target.setSource("system");
10400                                        targetName = targetColumn.getName();
10401                                        relationElement.setTarget(target);
10402                                } else if (targetElement instanceof TableRelationRows) {
10403                                        TableRelationRows targetColumn = (TableRelationRows) targetElement;
10404                                        targetColumn target = new targetColumn();
10405                                        target.setId(String.valueOf(targetColumn.getId()));
10406                                        target.setColumn(targetColumn.getName());
10407                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
10408                                        target.setParent_name(getTableName(targetColumn.getHolder()));
10409                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
10410                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
10411                                                                + convertCoordinate(targetColumn.getEndPosition()));
10412                                        }
10413                                        if (relation instanceof RecordSetRelationship) {
10414                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
10415                                        }
10416                                        target.setSource("system");
10417                                        targetName = targetColumn.getName();
10418                                        relationElement.setTarget(target);
10419                                } else if (targetElement instanceof ResultColumn) {
10420                                        ResultColumn targetColumn = (ResultColumn) targetElement;
10421                                        targetColumn target = new targetColumn();
10422                                        target.setId(String.valueOf(targetColumn.getId()));
10423                                        target.setColumn(targetColumn.getName());
10424                                        target.setStruct(targetColumn.isStruct());
10425                                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
10426                                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
10427                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
10428                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
10429                                                                + convertCoordinate(targetColumn.getEndPosition()));
10430                                        }
10431                                        if (relation instanceof RecordSetRelationship) {
10432                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
10433                                        }
10434                                        targetName = targetColumn.getName();
10435                                        if (((ResultColumn) targetColumn).getColumnObject() instanceof TResultColumn) {
10436                                                columnsInExpr visitor = new columnsInExpr();
10437                                                ((TResultColumn) ((ResultColumn) targetColumn).getColumnObject()).getExpr()
10438                                                                .inOrderTraverse(visitor);
10439                                                targetObjectNames = visitor.getObjectNames();
10440                                        }
10441
10442                                        if (targetElement instanceof FunctionResultColumn) {
10443                                                columnObject = ((FunctionResultColumn) targetElement).getColumnObject();
10444                                        }
10445                                        if(targetColumn.isPseduo()) {
10446                                                target.setSource("system");
10447                                        }
10448                                        relationElement.setTarget(target);
10449                                } else if (targetElement instanceof TableColumn) {
10450                                        TableColumn targetColumn = (TableColumn) targetElement;
10451                                        targetColumn target = new targetColumn();
10452                                        target.setId(String.valueOf(targetColumn.getId()));
10453                                        target.setColumn(targetColumn.getName());
10454                                        target.setStruct(targetColumn.isStruct());
10455                                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
10456                                        target.setParent_name(getTableName(targetColumn.getTable()));
10457                                        if (relation.getTarget() instanceof TableColumnRelationshipElement) {
10458                                                target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias());
10459                                        }
10460                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
10461                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
10462                                                                + convertCoordinate(targetColumn.getEndPosition()));
10463                                        }
10464                                        if (relation instanceof RecordSetRelationship) {
10465                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
10466                                        }
10467                                        if(targetColumn.isPseduo()) {
10468                                                target.setSource("system");
10469                                        }
10470                                        targetName = targetColumn.getName();
10471                                        relationElement.setTarget(target);
10472                                } else if (targetElement instanceof Argument) {
10473                                        Argument targetColumn = (Argument) targetElement;
10474                                        targetColumn target = new targetColumn();
10475                                        target.setId(String.valueOf(targetColumn.getId()));
10476                                        target.setColumn(targetColumn.getName());
10477                                        target.setParent_id(String.valueOf(targetColumn.getProcedure().getId()));
10478                                        target.setParent_name(targetColumn.getProcedure().getName());
10479                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
10480                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
10481                                                                + convertCoordinate(targetColumn.getEndPosition()));
10482                                        }
10483                                        if (relation instanceof RecordSetRelationship) {
10484                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
10485                                        }
10486                                        targetName = targetColumn.getName();
10487                                        relationElement.setTarget(target);
10488                                } else if (targetElement instanceof Table) {
10489                                        Table table = (Table) targetElement;
10490                                        targetColumn target = new targetColumn();
10491                                        target.setTarget_id(String.valueOf(table.getId()));
10492                                        target.setTarget_name(getTableName(table));
10493                                        if (table.getStartPosition() != null && table.getEndPosition() != null) {
10494                                                target.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
10495                                                                + convertCoordinate(table.getEndPosition()));
10496                                        }
10497                                        relationElement.setTarget(target);
10498                                } else {
10499                                        continue;
10500                                }
10501
10502                                Collection<RelationshipElement<?>> sourceElements = relation.getSources();
10503                                if (sourceElements.size() == 0) {
10504                                        if(clazz == CrudRelationship.class && option.getAnalyzeMode() == AnalyzeMode.crud) {
10505                                                dataflow.getRelationships().add(relationElement);
10506                                        }
10507                                        continue;
10508                                }
10509
10510                                boolean append = false;
10511                                for (RelationshipElement<?> sourceItem: relation.getSources()) {
10512                                        Object sourceElement = sourceItem.getElement();
10513                                        TObjectName sourceColumnName = null;
10514                                        if (sourceItem instanceof ResultColumnRelationshipElement) {
10515                                                sourceColumnName = ((ResultColumnRelationshipElement) sourceItem).getColumnName();
10516                                        }
10517//                                      if (sourceItem instanceof TableColumnRelationElement
10518//                                                      && (((TableColumnRelationElement) sourceItem).getColumnIndex() != null)) {
10519//                                              TableColumnRelationElement tableColumnRelationElement = (TableColumnRelationElement) sourceItem;
10520//                                              sourceElement = tableColumnRelationElement.getElement().getTable().getColumns()
10521//                                                              .get(tableColumnRelationElement.getColumnIndex() + 1);
10522//                                      }
10523                                        if (sourceElement instanceof ResultColumn) {
10524                                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
10525                                                if (sourceColumn.hasStarLinkColumn() && !relation.isShowStarRelation() && !sourceColumn.isPseduo()) {
10526                                                        List<String> sourceStarColumnNames = sourceColumn.getStarLinkColumnNames();
10527                                                        sourceColumn source = new sourceColumn();
10528                                                        if (targetObjectNames != null && !targetObjectNames.isEmpty()) {
10529
10530                                                                for (int k = 0; k < targetObjectNames.size(); k++) {
10531                                                                        String targetObjectName = getColumnName(targetObjectNames.get(k));
10532                                                                        if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
10533                                                                                boolean find = false;
10534                                                                                for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
10535                                                                                        if(column.getName().equalsIgnoreCase(targetObjectName)) {
10536                                                                                                source = new sourceColumn();
10537                                                                                                source.setId(String.valueOf(column.getId()));
10538                                                                                                source.setColumn(targetObjectName);
10539                                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10540                                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10541                                                                                                if (sourceColumn.getStartPosition() != null
10542                                                                                                                && sourceColumn.getEndPosition() != null) {
10543                                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
10544                                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
10545                                                                                                }
10546                                                                                                append = true;
10547                                                                                                relationElement.addSource(source);
10548                                                                                                find = true;
10549                                                                                                break;
10550                                                                                        }
10551                                                                                }
10552                                                                                if(find) {
10553                                                                                        continue;
10554                                                                                }
10555                                                                        }
10556                                                                        if (sourceColumn.getStarLinkColumns().containsKey(targetObjectName)) {
10557                                                                                source = new sourceColumn();
10558                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
10559                                                                                                + sourceStarColumnNames.indexOf(targetObjectName));
10560                                                                                source.setColumn(targetObjectName);
10561                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10562                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10563                                                                                if (sourceColumn.getStartPosition() != null
10564                                                                                                && sourceColumn.getEndPosition() != null) {
10565                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
10566                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
10567                                                                                }
10568                                                                                append = true;
10569                                                                                relationElement.addSource(source);
10570                                                                        } else {
10571                                                                                source = new sourceColumn();
10572                                                                                source.setId(String.valueOf(sourceColumn.getId()));
10573                                                                                source.setColumn(relationElement.getTarget().getColumn());
10574                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10575                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10576                                                                                if (sourceColumn.getStartPosition() != null
10577                                                                                                && sourceColumn.getEndPosition() != null) {
10578                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
10579                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
10580                                                                                }
10581                                                                                append = true;
10582                                                                                relationElement.addSource(source);
10583                                                                        }
10584                                                                }
10585                                                        } else {
10586                                                                if (columnObject instanceof TWhenClauseItemList) {
10587                                                                        TCaseExpression expr = (TCaseExpression)((FunctionResultColumn) targetElement).getResultSet().getGspObject();
10588                                                                        List<TExpression> directExpressions = new ArrayList<TExpression>();
10589                                                                        
10590//                                                                      TExpression inputExpr = expr.getInput_expr();
10591//                                                                      if (inputExpr != null) {
10592//                                                                              directExpressions.add(inputExpr);
10593//                                                                      }
10594                                                                        TExpression defaultExpr = expr.getElse_expr();
10595                                                                        if (defaultExpr != null) {
10596                                                                                directExpressions.add(defaultExpr);
10597                                                                        }
10598                                                                        TWhenClauseItemList list = expr.getWhenClauseItemList();
10599                                                                        for (int k = 0; k < list.size(); k++) {
10600                                                                                TWhenClauseItem element = list.getWhenClauseItem(k);
10601                                                                                directExpressions.add(element.getReturn_expr());
10602                                                                        }
10603                                                                        
10604                                                                        for (int k = 0; k < directExpressions.size(); k++) {
10605                                                                                columnsInExpr visitor = new columnsInExpr();
10606                                                                                directExpressions.get(k).inOrderTraverse(visitor);
10607                                                                                List<TObjectName> objectNames = visitor.getObjectNames();
10608                                                                                if (objectNames == null) {
10609                                                                                        continue;
10610                                                                                }
10611                                                                                for (int x = 0; x < objectNames.size(); x++) {
10612                                                                                        String objectName = getColumnName(objectNames.get(x));
10613                                                                                        if (sourceColumn.getStarLinkColumns().containsKey(objectName)) {
10614
10615                                                                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
10616                                                                                                        boolean find = false;
10617                                                                                                        for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
10618                                                                                                                if(column.getName().equalsIgnoreCase(objectName)) {
10619                                                                                                                        source = new sourceColumn();
10620                                                                                                                        source.setId(String.valueOf(column.getId()));
10621                                                                                                                        source.setColumn(objectName);
10622                                                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10623                                                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10624                                                                                                                        if (sourceColumn.getStartPosition() != null
10625                                                                                                                                        && sourceColumn.getEndPosition() != null) {
10626                                                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
10627                                                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
10628                                                                                                                        }
10629                                                                                                                        append = true;
10630                                                                                                                        relationElement.addSource(source);
10631                                                                                                                        find = true;
10632                                                                                                                        break;
10633                                                                                                                }
10634                                                                                                        }
10635                                                                                                        if(find) {
10636                                                                                                                continue;
10637                                                                                                        }
10638                                                                                                }
10639                                                                                                
10640                                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
10641                                                                                                                + sourceStarColumnNames.indexOf(objectName));
10642                                                                                                source.setColumn(objectName);
10643                                                                                        } else {
10644                                                                                                source.setId(String.valueOf(sourceColumn.getId()));
10645                                                                                                source.setColumn(sourceColumn.getName());
10646                                                                                        }
10647                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10648                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10649                                                                                        if (sourceColumn.getStartPosition() != null
10650                                                                                                        && sourceColumn.getEndPosition() != null) {
10651                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
10652                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
10653                                                                                        }
10654                                                                                        append = true;
10655                                                                                        relationElement.addSource(source);
10656                                                                                }
10657                                                                        }
10658                                                                } else {
10659                                                                        String objectName = getColumnName(targetName);
10660                                                                        boolean find = false;
10661                                                                        
10662                                                                        if (!find && sourceColumn.getStarLinkColumns().containsKey(objectName)) {
10663                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
10664                                                                                                + sourceStarColumnNames.indexOf(objectName));
10665                                                                                source.setColumn(objectName);
10666                                                                                find = true;
10667                                                                        }
10668
10669                                                                        if (!find && sourceColumnName != null) {
10670                                                                                objectName = getColumnName(sourceColumnName);
10671                                                                                
10672                                                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
10673                                                                                        for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
10674                                                                                                if(column.getName().equalsIgnoreCase(objectName)) {
10675                                                                                                        source = new sourceColumn();
10676                                                                                                        source.setId(String.valueOf(column.getId()));
10677                                                                                                        source.setColumn(objectName);
10678                                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10679                                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10680                                                                                                        if (sourceColumn.getStartPosition() != null
10681                                                                                                                        && sourceColumn.getEndPosition() != null) {
10682                                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
10683                                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
10684                                                                                                        }
10685                                                                                                        append = true;
10686                                                                                                        relationElement.addSource(source);
10687                                                                                                        find = true;
10688                                                                                                        break;
10689                                                                                                }
10690                                                                                        }
10691                                                                                        if(find) {
10692                                                                                                continue;
10693                                                                                        }
10694                                                                                }
10695                                                                                
10696                                                                                if (sourceColumn.getStarLinkColumns().containsKey(objectName)) {
10697                                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
10698                                                                                                        + sourceStarColumnNames.indexOf(objectName));
10699                                                                                        source.setColumn(objectName);
10700                                                                                        find = true;
10701                                                                                }
10702                                                                        }
10703                                                                        
10704                                                                        if (!find && sourceItem instanceof ResultColumnRelationshipElement) {
10705                                                                                int starIndex = ((ResultColumnRelationshipElement) sourceItem)
10706                                                                                                .getStarIndex();
10707                                                                                if (starIndex > -1 && sourceColumn.getStarLinkColumnList().size() > starIndex) {
10708                                                                                        objectName = getColumnName(sourceColumn.getStarLinkColumnList().get(starIndex));
10709                                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
10710                                                                                                        + starIndex);
10711                                                                                        source.setColumn(objectName);
10712                                                                                        find = true;
10713                                                                                }
10714                                                                        }
10715
10716                                                                        if (!find) {
10717                                                                                source.setId(String.valueOf(sourceColumn.getId()));
10718                                                                                source.setColumn(sourceColumn.getName());
10719                                                                        }
10720
10721                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10722                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10723                                                                        if (sourceColumn.getStartPosition() != null
10724                                                                                        && sourceColumn.getEndPosition() != null) {
10725                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10726                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
10727                                                                        }
10728                                                                        append = true;
10729                                                                        relationElement.addSource(source);
10730                                                                }
10731                                                        }
10732
10733                                                } else {
10734                                                        sourceColumn source = new sourceColumn();
10735                                                        source.setId(String.valueOf(sourceColumn.getId()));
10736                                                        source.setColumn(sourceColumn.getName());
10737                                                        source.setStruct(sourceColumn.isStruct());
10738                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
10739                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
10740                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10741                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10742                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
10743                                                        }
10744                                                        append = true;
10745                                                        if (sourceItem.getTransforms() != null) {
10746                                                                for (Transform transform : sourceItem.getTransforms()) {
10747                                                                        source.addTransform(transform);
10748                                                                }
10749                                                        }
10750                                                        if(sourceColumn.isPseduo()) {
10751                                                                source.setSource("system");
10752                                                        }
10753                                                        relationElement.addSource(source);
10754                                                }
10755                                        } else if (sourceElement instanceof TableColumn) {
10756                                                TableColumn sourceColumn = (TableColumn) sourceElement;
10757                                                if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()
10758                                                                && sourceItem instanceof TableColumnRelationshipElement) {
10759                                                        sourceColumn source = new sourceColumn();
10760                                                        boolean find = false;
10761                                                        if (((TableColumnRelationshipElement) sourceItem).getColumnIndex() != null) {
10762                                                                int columnIndex = ((TableColumnRelationshipElement) sourceItem).getColumnIndex();
10763                                                                if (sourceColumn.getStarLinkColumns().size() > columnIndex) {
10764                                                                        source = new sourceColumn();
10765                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + columnIndex);
10766                                                                        String targetObjectName = getColumnName(
10767                                                                                        sourceColumn.getStarLinkColumnList().get(columnIndex));
10768                                                                        source.setColumn(targetObjectName);
10769                                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
10770                                                                        source.setParent_name(sourceColumn.getTable().getName());
10771                                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
10772                                                                                source.setParent_alias(
10773                                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
10774                                                                        }
10775                                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10776                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10777                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
10778                                                                        }
10779                                                                        append = true;
10780                                                                        relationElement.addSource(source);
10781                                                                        find = true;
10782                                                                }
10783                                                        }
10784
10785                                                        if (!find) {
10786                                                                String objectName = getColumnName(targetName);
10787
10788                                                                table tableElement = null;
10789                                                                if (dataflow.getTables() != null) {
10790                                                                        for (table t : dataflow.getTables()) {
10791                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
10792                                                                                        tableElement = t;
10793                                                                                        break;
10794                                                                                }
10795                                                                        }
10796                                                                }
10797                                                                if (tableElement == null && dataflow.getViews() != null) {
10798                                                                        for (table t : dataflow.getViews()) {
10799                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
10800                                                                                        tableElement = t;
10801                                                                                        break;
10802                                                                                }
10803                                                                        }
10804                                                                }
10805                                                                if (tableElement == null && dataflow.getVariables() != null) {
10806                                                                        for (table t : dataflow.getVariables()) {
10807                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
10808                                                                                        tableElement = t;
10809                                                                                        break;
10810                                                                                }
10811                                                                        }
10812                                                                }
10813
10814                                                                if(tableElement!=null) {
10815                                                                        for (column column : tableElement.getColumns()) {
10816                                                                                if (column.getName().equalsIgnoreCase(objectName)) {
10817                                                                                        source = new sourceColumn();
10818                                                                                        source.setId(String.valueOf(column.getId()));
10819                                                                                        source.setColumn(objectName);
10820                                                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
10821                                                                                        source.setParent_name(sourceColumn.getTable().getName());
10822                                                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
10823                                                                                                source.setParent_alias(
10824                                                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
10825                                                                                        }
10826                                                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10827                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10828                                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
10829                                                                                        }
10830                                                                                        if (sourceItem.getTransforms() != null) {
10831                                                                                                for (Transform transform : sourceItem.getTransforms()) {
10832                                                                                                        source.addTransform(transform);
10833                                                                                                }
10834                                                                                        }
10835                                                                                        if (sourceColumn.getCandidateParents() != null) {
10836                                                                                                for(Object item: sourceColumn.getCandidateParents()) {
10837                                                                                                        candidateTable candidateParent = new candidateTable();
10838                                                                                                        if(item instanceof Table) {
10839                                                                                                                candidateParent.setId(String.valueOf(((Table)item).getId()));
10840                                                                                                                candidateParent.setName(getTableName((Table)item));
10841                                                                                                                source.addCandidateParent(candidateParent);
10842                                                                                                        }
10843                                                                                                        else if(item instanceof ResultSet) {
10844                                                                                                                candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
10845                                                                                                                candidateParent.setName(getResultSetName((ResultSet)item));
10846                                                                                                                source.addCandidateParent(candidateParent);
10847                                                                                                        }
10848                                                                                                }
10849                                                                                        }
10850                                                                                        append = true;
10851                                                                                        relationElement.addSource(source);
10852                                                                                        find = true;
10853                                                                                        break;
10854                                                                                }
10855                                                                        }
10856                                                                }
10857                                                        }
10858
10859                                                        if(!find) {
10860                                                                source = new sourceColumn();
10861                                                                source.setId(String.valueOf(sourceColumn.getId()));
10862                                                                source.setColumn(relationElement.getTarget().getColumn());
10863                                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
10864                                                                source.setParent_name(sourceColumn.getTable().getName());
10865                                                                if (sourceItem instanceof TableColumnRelationshipElement) {
10866                                                                        source.setParent_alias(
10867                                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
10868                                                                }
10869                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10870                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10871                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
10872                                                                }
10873                                                                if (sourceItem.getTransforms() != null) {
10874                                                                        for (Transform transform : sourceItem.getTransforms()) {
10875                                                                                source.addTransform(transform);
10876                                                                        }
10877                                                                }
10878                                                                if (sourceColumn.getCandidateParents() != null) {
10879                                                                        for(Object item: sourceColumn.getCandidateParents()) {
10880                                                                                candidateTable candidateParent = new candidateTable();
10881                                                                                if(item instanceof Table) {
10882                                                                                        candidateParent.setId(String.valueOf(((Table)item).getId()));
10883                                                                                        candidateParent.setName(getTableName((Table)item));
10884                                                                                        source.addCandidateParent(candidateParent);
10885                                                                                }
10886                                                                                else if(item instanceof ResultSet) {
10887                                                                                        candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
10888                                                                                        candidateParent.setName(getResultSetName((ResultSet)item));
10889                                                                                        source.addCandidateParent(candidateParent);
10890                                                                                }
10891                                                                        }
10892                                                                }
10893                                                                append = true;
10894                                                                relationElement.addSource(source);
10895                                                        }
10896
10897                                                } else {
10898                                                        sourceColumn source = new sourceColumn();
10899                                                        source.setId(String.valueOf(sourceColumn.getId()));
10900                                                        source.setColumn(sourceColumn.getName());
10901                                                        source.setStruct(sourceColumn.isStruct());
10902                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
10903                                                        source.setParent_name(getTableName(sourceColumn.getTable()));
10904                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
10905                                                                source.setParent_alias(
10906                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
10907                                                        }
10908                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10909                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10910                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
10911                                                        }
10912                                                        if (sourceItem.getTransforms() != null) {
10913                                                                for (Transform transform : sourceItem.getTransforms()) {
10914                                                                        source.addTransform(transform);
10915                                                                }
10916                                                        }
10917                                                        if(sourceColumn.isPseduo()) {
10918                                                                source.setSource("system");
10919                                                        }
10920                                                        if (sourceColumn.getCandidateParents() != null) {
10921                                                                for(Object item: sourceColumn.getCandidateParents()) {
10922                                                                        candidateTable candidateParent = new candidateTable();
10923                                                                        if(item instanceof Table) {
10924                                                                                candidateParent.setId(String.valueOf(((Table)item).getId()));
10925                                                                                candidateParent.setName(getTableName((Table)item));
10926                                                                                source.addCandidateParent(candidateParent);
10927                                                                        }
10928                                                                        else if(item instanceof ResultSet) {
10929                                                                                candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
10930                                                                                candidateParent.setName(getResultSetName((ResultSet)item));
10931                                                                                source.addCandidateParent(candidateParent);
10932                                                                        }
10933                                                                }
10934                                                        }
10935                                                        append = true;
10936                                                        relationElement.addSource(source);
10937                                                }
10938                                        } else if (sourceElement instanceof Argument) {
10939                                                Argument sourceColumn = (Argument) sourceElement;
10940                                                sourceColumn source = new sourceColumn();
10941                                                source.setId(String.valueOf(sourceColumn.getId()));
10942                                                source.setColumn(sourceColumn.getName());
10943                                                source.setParent_id(String.valueOf(sourceColumn.getProcedure().getId()));
10944                                                source.setParent_name(sourceColumn.getProcedure().getName());
10945                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10946                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10947                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
10948                                                }
10949                                                append = true;
10950                                                relationElement.addSource(source);
10951                                        } else if (sourceElement instanceof TableRelationRows) {
10952                                                TableRelationRows sourceColumn = (TableRelationRows) sourceElement;
10953                                                sourceColumn source = new sourceColumn();
10954                                                source.setId(String.valueOf(sourceColumn.getId()));
10955                                                source.setColumn(sourceColumn.getName());
10956                                                source.setParent_id(String.valueOf(sourceColumn.getHolder().getId()));
10957                                                source.setParent_name(getTableName(sourceColumn.getHolder()));
10958                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10959                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10960                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
10961                                                }
10962                                                source.setSource("system");
10963                                                append = true;
10964                                                relationElement.addSource(source);
10965                                        } else if (sourceElement instanceof ResultSetRelationRows) {
10966                                                ResultSetRelationRows sourceColumn = (ResultSetRelationRows) sourceElement;
10967                                                sourceColumn source = new sourceColumn();
10968                                                source.setId(String.valueOf(sourceColumn.getId()));
10969                                                source.setColumn(sourceColumn.getName());
10970                                                source.setParent_id(String.valueOf(sourceColumn.getHolder().getId()));
10971                                                source.setParent_name(getResultSetName(sourceColumn.getHolder()));
10972                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10973                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10974                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
10975                                                }
10976                                                source.setSource("system");
10977                                                append = true;
10978                                                relationElement.addSource(source);
10979                                        } else if (sourceElement instanceof Constant) {
10980                                                Constant sourceColumn = (Constant) sourceElement;
10981                                                sourceColumn source = new sourceColumn();
10982                                                source.setId(String.valueOf(sourceColumn.getId()));
10983                                                source.setColumn(sourceColumn.getName());
10984                                                source.setColumn_type("constant");
10985                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
10986                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
10987                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
10988                                                }
10989                                                append = true;
10990                                                relationElement.addSource(source);
10991                                        } else if (sourceElement instanceof Table) {
10992                                                Table table = (Table) sourceElement;
10993                                                sourceColumn source = new sourceColumn();
10994                                                source.setSource_id(String.valueOf(table.getId()));
10995                                                source.setSource_name(getTableName(table));
10996                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
10997                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
10998                                                                        + convertCoordinate(table.getEndPosition()));
10999                                                }
11000                                                append = true;
11001                                                relationElement.addSource(source);
11002                                        }
11003
11004                                        if (relation instanceof ImpactRelationship) {
11005                                                ESqlClause clause = getSqlClause(sourceItem);
11006                                                if (clause != null
11007                                                                && (relationElement.getSources() != null && !relationElement.getSources().isEmpty())) {
11008                                                        relationElement.getSources().get(relationElement.getSources().size() - 1)
11009                                                                        .setClauseType(clause.name());
11010                                                }
11011                                        }
11012                                }
11013                                if (append)
11014                                        dataflow.getRelationships().add(relationElement);
11015                        }
11016                }
11017        }
11018
11019        private boolean containsStar(Collection<RelationshipElement<?>> elements) {
11020                if (elements == null || elements.size() == 0)
11021                        return false;
11022
11023                for (RelationshipElement<?> element : elements) {
11024                        if (element.getElement() instanceof ResultColumn) {
11025                                ResultColumn object = (ResultColumn) element.getElement();
11026                                if (object.getName().endsWith("*") && object.isShowStar())
11027                                        return true;
11028                        } else if (element.getElement() instanceof TableColumn) {
11029                                TableColumn object = (TableColumn) element.getElement();
11030                                if (object.getName().endsWith("*") && object.isShowStar())
11031                                        return true;
11032                        }
11033                }
11034                return false;
11035        }
11036
11037        private Map<String, Set<String>> appendTableStarColumns = new HashMap<String, Set<String>>();
11038        private void updateResultColumnStarLinks(dataflow dataflow, AbstractRelationship relation, int index) {
11039                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
11040                        return;
11041                }
11042                
11043                ResultColumn targetColumn = (ResultColumn) relation.getTarget().getElement();
11044                
11045                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
11046                if (sourceElements == null || sourceElements.size() == 0)
11047                        return;
11048
11049                for (RelationshipElement<?> sourceItem: sourceElements) {
11050                        Object sourceElement = sourceItem.getElement();
11051                        if (sourceElement instanceof ResultColumn) {
11052                                ResultColumn source = (ResultColumn) sourceElement;
11053                                if (source.hasStarLinkColumn()) {
11054                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11055                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11056                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11057                                                }
11058                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11059                                        }
11060                                        if (!source.isShowStar()) {
11061                                                targetColumn.setShowStar(false);
11062                                                relation.setShowStarRelation(false);
11063                                        }
11064                                } else if (!"*".equals(source.getName())) {
11065                                        if (source.getColumnObject() instanceof TObjectName) {
11066                                                if (source instanceof FunctionResultColumn) {
11067
11068                                                } else {
11069                                                        targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject());
11070                                                }
11071                                        } else if (source.getColumnObject() instanceof TResultColumn) {
11072                                                TResultColumn sourceColumn = (TResultColumn) source.getColumnObject();
11073                                                if (sourceColumn.getAliasClause() != null) {
11074                                                        targetColumn.bindStarLinkColumn(sourceColumn.getAliasClause().getAliasName());
11075                                                } else if (sourceColumn.getFieldAttr() != null) {
11076                                                        targetColumn.bindStarLinkColumn(sourceColumn.getFieldAttr());
11077                                                } else {
11078                                                        TObjectName column = new TObjectName();
11079                                                        if (sourceColumn.getExpr().getExpressionType() == EExpressionType.typecast_t) {
11080                                                                column.setString(sourceColumn.getExpr().getLeftOperand().toString());
11081                                                        } else {
11082                                                                column.setString(sourceColumn.toString());
11083                                                        }
11084                                                        targetColumn.bindStarLinkColumn(column);
11085                                                }
11086                                        }
11087                                }
11088                        } else if (sourceElement instanceof TableColumn) {
11089                                TableColumn source = (TableColumn) sourceElement;
11090                                if (!source.isPseduo() && source.hasStarLinkColumn()) {
11091                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11092                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11093                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11094                                                }
11095                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11096                                        }
11097                                        if ((source.getTable().isCreateTable() || source.getTable().hasSQLEnv()) && !source.isShowStar()) {
11098                                                targetColumn.setShowStar(false);
11099                                                relation.setShowStarRelation(false);
11100                                        }
11101
11102                                } else if (!"*".equals(source.getName())) {
11103                                        targetColumn.bindStarLinkColumn(source.getColumnObject());
11104                                }
11105                        }
11106                }
11107
11108                if (targetColumn.hasStarLinkColumn()) {
11109                        table resultSetElement = null;
11110                        for (table t : dataflow.getResultsets()) {
11111                                if (t.getId().equals(String.valueOf(targetColumn.getResultSet().getId()))) {
11112                                        resultSetElement = t;
11113                                        break;
11114                                }
11115                        }
11116                        if (resultSetElement != null) {
11117                                List<String> columns = targetColumn.getStarLinkColumnNames();
11118                                if (index == -1) {
11119                                        for (int k = 0; k < columns.size(); k++) {
11120                                                String columnName = columns.get(k);
11121                                                String id = String.valueOf(targetColumn.getId()) + "_" + k;
11122                                                if(appendTableStarColumns.containsKey(resultSetElement.getId()) && appendTableStarColumns.get(resultSetElement.getId()).contains(id)) {
11123                                                        continue;
11124                                                }
11125                                                column columnElement = new column();
11126                                                columnElement.setId(id);
11127                                                columnElement.setName(columnName);
11128                                                if (targetColumn.isFunction()) {
11129                                                        columnElement.setIsFunction(String.valueOf(targetColumn.isFunction()));
11130                                                }
11131                                                if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11132                                                        columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11133                                                                        + convertCoordinate(targetColumn.getEndPosition()));
11134                                                }
11135
11136                                                if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) {
11137                                                        boolean find = false;
11138                                                        for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
11139                                                                ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
11140                                                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName())
11141                                                                                .equals(columnName)) {
11142                                                                        find = true;
11143                                                                        break;
11144                                                                }
11145                                                        }
11146                                                        if (find) {
11147                                                                continue;
11148                                                        }
11149                                                }
11150                                                
11151                                                if (!resultSetElement.getColumns().contains(columnElement)) {
11152                                                        resultSetElement.getColumns().add(columnElement);
11153                                                        appendTableStarColumns.putIfAbsent(resultSetElement.getId(), new HashSet<String>());
11154                                                        appendTableStarColumns.get(resultSetElement.getId()).add(id);
11155                                                }
11156                                        }
11157                                }
11158                                else {
11159                                        int k = index;
11160                                        String columnName = columns.get(k);
11161                                        column columnElement = new column();
11162                                        columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k);
11163                                        columnElement.setName(columnName);
11164                                        if (targetColumn.isFunction()) {
11165                                                columnElement.setIsFunction(String.valueOf(targetColumn.isFunction()));
11166                                        }
11167                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11168                                                columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11169                                                                + convertCoordinate(targetColumn.getEndPosition()));
11170                                        }
11171
11172                                        if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) {
11173                                                boolean find = false;
11174                                                for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
11175                                                        ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
11176                                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
11177                                                                find = true;
11178                                                                break;
11179                                                        }
11180                                                }
11181                                                if (find) {
11182                                                        return;
11183                                                }
11184                                        }
11185
11186                                        if (!resultSetElement.getColumns().contains(columnElement)) {
11187                                                resultSetElement.getColumns().add(columnElement);
11188                                        }
11189                                }
11190                        }
11191                }
11192        }
11193
11194        private void updateTableColumnStarLinks(dataflow dataflow, AbstractRelationship relation) {
11195                TableColumn targetColumn = (TableColumn) relation.getTarget().getElement();             
11196                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
11197                if (sourceElements == null || sourceElements.size() == 0)
11198                        return;
11199
11200                TableColumn sourceStarColumn = null;
11201
11202                for (RelationshipElement<?> sourceItem: sourceElements) {
11203                        Object sourceElement = sourceItem.getElement();
11204                        if (sourceElement instanceof ResultColumn) {
11205                                ResultColumn source = (ResultColumn) sourceElement;
11206                                if(source.getResultSet() instanceof Function) {
11207                                        continue;
11208                                }
11209                                if (source.hasStarLinkColumn()) {
11210                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11211                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11212                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11213                                                }
11214                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11215                                        }
11216                                        if (!source.isShowStar()) {
11217                                                targetColumn.setShowStar(false);
11218                                                relation.setShowStarRelation(false);
11219                                        }
11220                                } else if (!"*".equals(source.getName())) {
11221                                        if (source.getColumnObject() instanceof TObjectName) {
11222                                                targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject());
11223                                        } else if (source.getColumnObject() instanceof TResultColumn) {
11224                                                if (((TResultColumn) source.getColumnObject()).getAliasClause() != null) {
11225                                                        TObjectName field = ((TResultColumn) source.getColumnObject()).getAliasClause()
11226                                                                        .getAliasName();
11227                                                        if (field != null) {
11228                                                                targetColumn.bindStarLinkColumn(field);
11229                                                        }
11230                                                } else {
11231                                                        TObjectName field = ((TResultColumn) source.getColumnObject()).getFieldAttr();
11232                                                        if (field != null) {
11233                                                                targetColumn.bindStarLinkColumn(field);
11234                                                        } else {
11235                                                                TObjectName column = new TObjectName();
11236                                                                if (((TResultColumn) source.getColumnObject()).getExpr()
11237                                                                                .getExpressionType() == EExpressionType.typecast_t) {
11238                                                                        column.setString(((TResultColumn) source.getColumnObject()).getExpr()
11239                                                                                        .getLeftOperand().toString());
11240                                                                } else {
11241                                                                        column.setString(((TResultColumn) source.getColumnObject()).toString());
11242                                                                }
11243                                                                targetColumn.bindStarLinkColumn(column);
11244                                                        }
11245                                                }
11246                                        }
11247                                }
11248                        } else if (sourceElement instanceof TableColumn) {
11249                                TableColumn source = (TableColumn) sourceElement;
11250                                if (source.hasStarLinkColumn()) {
11251                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11252                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11253                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11254                                                }
11255                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11256                                        }
11257                                        for (Map.Entry<String, Set<TObjectName>> item : targetColumn.getStarLinkColumns().entrySet()) {
11258                                                if (!source.getStarLinkColumns().containsKey(item.getKey())) {
11259                                                        source.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11260                                                }
11261                                                source.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11262                                        }
11263
11264                                        sourceStarColumn = source;
11265
11266                                        if (source.getTable().isCreateTable() && !source.isShowStar()) {
11267                                                targetColumn.setShowStar(false);
11268                                                relation.setShowStarRelation(false);
11269                                        }
11270                                } else if (!"*".equals(source.getName())) {
11271                                        if (source.isStruct()) {
11272                                                targetColumn.bindStarLinkColumn(source.getColumnObject());
11273                                        }
11274                                        else {
11275                                                TObjectName objectName = new TObjectName();
11276                                                objectName.setString(DlineageUtil.getColumnNameOnly(source.getName()));
11277                                                targetColumn.bindStarLinkColumn(objectName);
11278                                        }
11279                                }
11280                        }
11281                }
11282
11283                if (targetColumn.hasStarLinkColumn()) {
11284                        table tableElement = null;
11285                        if (dataflow.getTables() != null) {
11286                                for (table t : dataflow.getTables()) {
11287                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
11288                                                tableElement = t;
11289                                                break;
11290                                        }
11291                                }
11292                        }
11293                        if (tableElement == null && dataflow.getViews() != null) {
11294                                for (table t : dataflow.getViews()) {
11295                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
11296                                                tableElement = t;
11297                                                break;
11298                                        }
11299                                }
11300                        }
11301                        if (tableElement == null && dataflow.getVariables() != null) {
11302                                for (table t : dataflow.getVariables()) {
11303                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
11304                                                tableElement = t;
11305                                                break;
11306                                        }
11307                                }
11308                        }
11309
11310                        if (tableElement != null) {
11311                                List<String> columns = new ArrayList<String>(targetColumn.getStarLinkColumns().keySet());
11312                                for (int k = 0; k < columns.size(); k++) {
11313                                        String columnName = columns.get(k);
11314                                        if (containStarColumn(targetColumn.getTable().getColumns(), columnName)) {
11315                                                continue;
11316                                        }
11317                                        column columnElement = new column();
11318                                        columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k);
11319                                        columnElement.setName(columnName);
11320                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11321                                                columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11322                                                                + convertCoordinate(targetColumn.getEndPosition()));
11323                                        }
11324                                        if (!tableElement.getColumns().contains(columnElement)) {
11325                                                tableElement.getColumns().add(columnElement);
11326                                        }
11327                                }
11328                        }
11329                }
11330
11331                if (sourceStarColumn != null) {
11332                        table tableElement = null;
11333                        if (dataflow.getTables() != null) {
11334                                for (table t : dataflow.getTables()) {
11335                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
11336                                                tableElement = t;
11337                                                break;
11338                                        }
11339                                }
11340                        }
11341                        if (tableElement == null && dataflow.getViews() != null) {
11342                                for (table t : dataflow.getViews()) {
11343                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
11344                                                tableElement = t;
11345                                                break;
11346                                        }
11347                                }
11348                        }
11349                        if (tableElement == null && dataflow.getVariables() != null) {
11350                                for (table t : dataflow.getVariables()) {
11351                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
11352                                                tableElement = t;
11353                                                break;
11354                                        }
11355                                }
11356                        }
11357
11358                        if (tableElement != null) {
11359                                List<String> columns = new ArrayList<String>(sourceStarColumn.getStarLinkColumns().keySet());
11360                                for (int k = 0; k < columns.size(); k++) {
11361                                        String columnName = columns.get(k);
11362                                        if (containStarColumn(sourceStarColumn.getTable().getColumns(), columnName)) {
11363                                                continue;
11364                                        }
11365                                        column columnElement = new column();
11366                                        columnElement.setId(sourceStarColumn.getId() + "_" + k);
11367                                        columnElement.setName(columnName);
11368                                        if (sourceStarColumn.getStartPosition() != null && sourceStarColumn.getEndPosition() != null) {
11369                                                columnElement.setCoordinate(convertCoordinate(sourceStarColumn.getStartPosition()) + ","
11370                                                                + convertCoordinate(sourceStarColumn.getEndPosition()));
11371                                        }
11372                                        if (!tableElement.getColumns().contains(columnElement)) {
11373                                                tableElement.getColumns().add(columnElement);
11374                                        }
11375                                }
11376                        }
11377                }
11378        }
11379
11380        private ESqlClause getSqlClause(RelationshipElement<?> relationshipElement) {
11381                if (relationshipElement instanceof TableColumnRelationshipElement) {
11382                        return ((TableColumnRelationshipElement) relationshipElement).getRelationLocation();
11383                } else if (relationshipElement instanceof ResultColumnRelationshipElement) {
11384                        return ((ResultColumnRelationshipElement) relationshipElement).getRelationLocation();
11385                }
11386                return null;
11387        }
11388
11389        private void appendStarRelation(dataflow dataflow, AbstractRelationship relation, int index) {
11390                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
11391                        return;
11392                }
11393                
11394                Object targetElement = relation.getTarget().getElement();
11395
11396                relationship relationElement = new relationship();
11397                relationElement.setType(relation.getRelationshipType().name());
11398                if (relation.getEffectType() != null) {
11399                        relationElement.setEffectType(relation.getEffectType().name());
11400                }
11401                relationElement.setSqlHash(relation.getSqlHash());
11402                relationElement.setSqlComment(relation.getSqlComment());
11403
11404                if (relation.getProcedureId() != null) {
11405                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11406                }
11407                relationElement.setId(String.valueOf(relation.getId()) + "_" + index);
11408                if (relation.getProcess() != null) {
11409                        relationElement.setProcessId(String.valueOf(relation.getProcess().getId()));
11410                        if (relation.getProcess().getGspObject() != null) {
11411                                relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name());
11412                        }
11413                }
11414                if (relation instanceof DataFlowRelationship) {
11415                        relationElement.setSqlHash(((DataFlowRelationship) relation).getSqlHash());
11416                        relationElement.setSqlComment(((DataFlowRelationship) relation).getSqlComment());
11417                
11418                        if (relation.getProcedureId() != null) {
11419                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11420                        }
11421                }
11422                String targetName = "";
11423
11424                if (targetElement instanceof ResultColumn) {
11425                        ResultColumn targetColumn = (ResultColumn) targetElement;
11426
11427                        targetName = targetColumn.getStarLinkColumnNames().get(index);
11428
11429                        
11430                        targetColumn target = new targetColumn();
11431                        target.setId(String.valueOf(targetColumn.getId()) + "_" + index);
11432                        if(targetColumn.getResultSet()!=null && targetColumn.getResultSet().getColumns()!=null) {
11433                                for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
11434                                        ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
11435                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(targetName)) {
11436                                                target.setId(String.valueOf(columnModel.getId()));
11437                                                break;
11438                                        }
11439                                }
11440                        }
11441                        target.setColumn(targetName);
11442                        target.setStruct(targetColumn.isStruct());
11443                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
11444                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
11445                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11446                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11447                                                + convertCoordinate(targetColumn.getEndPosition()));
11448                        }
11449                        relationElement.setTarget(target);
11450                } else if (targetElement instanceof TableColumn) {
11451                        TableColumn targetColumn = (TableColumn) targetElement;
11452
11453                        targetName = targetColumn.getStarLinkColumnNames().get(index);
11454
11455                        TableColumn tableColumn = searchTableColumn(targetColumn.getTable().getColumns(), targetName);
11456
11457                        targetColumn target = new targetColumn();
11458                        if (tableColumn == null) {
11459                                target.setId(targetColumn.getId() + "_" + index);
11460                        } else {
11461                                target.setId(String.valueOf(tableColumn.getId()));
11462                        }
11463                        target.setStruct(targetColumn.isStruct());
11464                        target.setColumn(targetName);
11465                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
11466                        target.setParent_name(targetColumn.getTable().getName());
11467                        if (relation.getTarget() instanceof TableColumnRelationshipElement) {
11468                                target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias());
11469                        }
11470                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11471                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11472                                                + convertCoordinate(targetColumn.getEndPosition()));
11473                        }
11474                        relationElement.setTarget(target);
11475                } else {
11476                        return;
11477                }
11478
11479                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
11480                if (sourceElements.size() == 0) {
11481                        return;
11482                }
11483
11484                String targetIdentifierName = DlineageUtil.getIdentifierNormalColumnName(targetName);
11485                if (targetIdentifierName == null) {
11486                        return;
11487                }
11488                for (RelationshipElement<?> sourceItem: sourceElements) {
11489                        Object sourceElement = sourceItem.getElement();
11490                        if (sourceElement instanceof ResultColumn) {
11491                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
11492                                if (sourceColumn.hasStarLinkColumn()) {
11493                                        List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames();
11494                                        int linkColumnNameSize = linkColumnNames.size();
11495                                        for (int k = 0; k < linkColumnNameSize; k++) {
11496                                                String sourceName = linkColumnNames.get(k);
11497                                                if (relation.getRelationshipType() == RelationshipType.fdd) {
11498                                                        if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName))
11499                                                                continue;
11500                                                }
11501                                                sourceColumn source = new sourceColumn();                                               
11502                                                
11503                                                boolean find = false;
11504                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11505                                                        for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) {
11506                                                                ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i);
11507                                                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(sourceName)) {
11508                                                                        source.setId(String.valueOf(columnModel.getId()));
11509                                                                        find = true;
11510                                                                        break;
11511                                                                }
11512                                                        }
11513                                                }
11514                                                if(!find) {
11515                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + k);
11516                                                }
11517                                                source.setColumn(sourceName);
11518                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11519                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11520                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11521                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11522                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11523                                                }
11524                                                if (sourceItem.getTransforms() != null) {
11525                                                        for (Transform transform : sourceItem.getTransforms()) {
11526                                                                source.addTransform(transform);
11527                                                        }
11528                                                }
11529                                                relationElement.addSource(source);
11530                                        }
11531                                        if(relationElement.getSources().isEmpty() && sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11532                                                for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) {
11533                                                        ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i);
11534                                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equalsIgnoreCase(targetIdentifierName)) {
11535                                                                sourceColumn source = new sourceColumn();
11536                                                                source.setId(String.valueOf(columnModel.getId()));
11537                                                                source.setColumn(columnModel.getName());
11538                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11539                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11540                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11541                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11542                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11543                                                                }
11544                                                                if (sourceItem.getTransforms() != null) {
11545                                                                        for (Transform transform : sourceItem.getTransforms()) {
11546                                                                                source.addTransform(transform);
11547                                                                        }
11548                                                                }
11549                                                                relationElement.addSource(source);
11550                                                                break;
11551                                                        }
11552                                                }
11553                                        }
11554                                        if (relationElement.getSources().isEmpty()) {
11555                                                TObjectName sourceStarLinkColumn = new TObjectName();
11556                                                sourceStarLinkColumn.setString(targetName);
11557                                                boolean newBinding = sourceColumn.bindStarLinkColumn(sourceStarLinkColumn);
11558                                                sourceColumn source = new sourceColumn();
11559                                                String sourceName = DlineageUtil.getColumnName(sourceStarLinkColumn);
11560                                                if (!newBinding) {
11561                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
11562                                                                        + sourceColumn.indexOfStarLinkColumn(sourceStarLinkColumn));
11563                                                } else {
11564                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize);
11565                                                }
11566                                                source.setColumn(sourceName);
11567                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11568                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11569                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11570                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11571                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11572                                                }
11573                                                if (sourceItem.getTransforms() != null) {
11574                                                        for (Transform transform : sourceItem.getTransforms()) {
11575                                                                source.addTransform(transform);
11576                                                        }
11577                                                }
11578                                                relationElement.addSource(source);
11579
11580                                                if (newBinding) {
11581                                                        table resultSetElement = null;
11582                                                        for (table t : dataflow.getResultsets()) {
11583                                                                if (t.getId().equals(String.valueOf(sourceColumn.getResultSet().getId()))) {
11584                                                                        resultSetElement = t;
11585                                                                        break;
11586                                                                }
11587                                                        }
11588                                                        if (resultSetElement != null) {
11589                                                                column columnElement = new column();
11590                                                                columnElement.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize);
11591                                                                columnElement.setName(sourceName);
11592                                                                if (sourceColumn.isFunction()) {
11593                                                                        columnElement.setIsFunction(String.valueOf(sourceColumn.isFunction()));
11594                                                                }
11595                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11596                                                                        columnElement.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11597                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11598                                                                }
11599                                                                resultSetElement.getColumns().add(columnElement);
11600                                                        }
11601                                                }
11602                                        }
11603                                } else {
11604                                        sourceColumn source = new sourceColumn();
11605                                        source.setId(String.valueOf(sourceColumn.getId()));
11606                                        source.setColumn(sourceColumn.getName());
11607                                        source.setStruct(sourceColumn.isStruct());
11608                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11609                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11610                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11611                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11612                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11613                                        }
11614                                        if (relation.getRelationshipType() == RelationshipType.fdd) {
11615                                                if (!targetIdentifierName
11616                                                                .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))
11617                                                                && !"*".equals(sourceColumn.getName()))
11618                                                        continue;
11619                                        }
11620                                        if (sourceItem.getTransforms() != null) {
11621                                                for (Transform transform : sourceItem.getTransforms()) {
11622                                                        source.addTransform(transform);
11623                                                }
11624                                        }
11625                                        relationElement.addSource(source);
11626                                }
11627                        } else if (sourceElement instanceof TableColumn) {
11628                                TableColumn sourceColumn = (TableColumn) sourceElement;
11629                                if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()) {
11630                                        List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames();
11631                                        int linkColumnNameSize = linkColumnNames.size();
11632                                        for (int k = 0; k < linkColumnNameSize; k++) {
11633                                                String sourceName = linkColumnNames.get(k);
11634                                                if (relation.getRelationshipType() == RelationshipType.fdd) {
11635                                                        if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName))
11636                                                                continue;
11637                                                }
11638
11639                                                TableColumn tableColumn = searchTableColumn(sourceColumn.getTable().getColumns(), sourceName);
11640
11641                                                sourceColumn source = new sourceColumn();
11642                                                if (tableColumn == null) {
11643                                                        source.setId(sourceColumn.getId() + "_" + k);
11644                                                } else {
11645                                                        source.setId(String.valueOf(tableColumn.getId()));
11646                                                }
11647                                                source.setColumn(sourceName);
11648                                                source.setStruct(sourceColumn.isStruct());
11649                                                if (containStarColumn(sourceElements, sourceName)) {
11650                                                        continue;
11651                                                }
11652                                                if (sourceColumn.getTable().getColumns().size() > 1) {
11653                                                        for (int y = 0; y < sourceColumn.getTable().getColumns().size(); y++) {
11654                                                                if (sourceColumn.getTable().getColumns().get(y).getName()
11655                                                                                .equalsIgnoreCase(sourceName)) {
11656                                                                        source.setId(String.valueOf(sourceColumn.getTable().getColumns().get(y).getId()));
11657                                                                        break;
11658                                                                }
11659                                                        }
11660                                                }
11661                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11662                                                source.setParent_name(getTableName(sourceColumn.getTable()));
11663                                                if (sourceItem instanceof TableColumnRelationshipElement) {
11664                                                        source.setParent_alias(
11665                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11666                                                }
11667                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11668                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11669                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11670                                                }
11671                                                if (sourceItem.getTransforms() != null) {
11672                                                        for (Transform transform : sourceItem.getTransforms()) {
11673                                                                source.addTransform(transform);
11674                                                        }
11675                                                }
11676                                                relationElement.addSource(source);
11677                                        }
11678                                } else {
11679                                        sourceColumn source = new sourceColumn();
11680                                        source.setId(String.valueOf(sourceColumn.getId()));
11681                                        source.setColumn(sourceColumn.getName());
11682                                        source.setStruct(sourceColumn.isStruct());
11683                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11684                                        source.setParent_name(getTableName(sourceColumn.getTable()));
11685                                        if (sourceItem instanceof TableColumnRelationshipElement) {
11686                                                source.setParent_alias(((TableColumnRelationshipElement) sourceItem).getTableAlias());
11687                                        }
11688                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11689                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11690                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11691                                        }
11692                                        if (relation.getRelationshipType() == RelationshipType.fdd) {
11693                                                if (!targetIdentifierName
11694                                                                .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))
11695                                                                && !"*".equals(sourceColumn.getName()))
11696                                                        continue;
11697                                        }
11698                                        if (sourceItem.getTransforms() != null) {
11699                                                for (Transform transform : sourceItem.getTransforms()) {
11700                                                        source.addTransform(transform);
11701                                                }
11702                                        }
11703                                        relationElement.addSource(source);
11704                                }
11705                        }
11706                }
11707
11708                if (relationElement.getTarget() != null && relationElement.getSources() != null
11709                                && !relationElement.getSources().isEmpty()) {
11710                        dataflow.getRelationships().add(relationElement);
11711                }
11712        }
11713
11714        private String getColumnName(TObjectName column) {
11715                if (column == null) {
11716                        return null;
11717                }
11718                String name = column.getColumnNameOnly();
11719                if (name == null || "".equals(name.trim())) {
11720                        return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim());
11721                } else
11722                        return DlineageUtil.getIdentifierNormalColumnName(name.trim());
11723        }
11724
11725        private String getColumnName(String column) {
11726                if (column == null) {
11727                        return null;
11728                }
11729                String name = column.substring(column.lastIndexOf(".") + 1);
11730                if (name == null || "".equals(name.trim())) {
11731                        return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim());
11732                } else
11733                        return DlineageUtil.getIdentifierNormalColumnName(name.trim());
11734        }
11735        
11736        private String getColumnNameOnly(String column) {
11737                if (column == null) {
11738                        return null;
11739                }
11740                return DlineageUtil.getColumnNameOnly(column);
11741        }
11742
11743        private void appendRecordSetRelation(dataflow dataflow, Relationship[] relations) {
11744                for (int i = 0; i < relations.length; i++) {
11745                        AbstractRelationship relation = (AbstractRelationship) relations[i];
11746                        relationship relationElement = new relationship();
11747                        relationElement.setType(relation.getRelationshipType().name());
11748                        if (relation.getFunction() != null) {
11749                                relationElement.setFunction(relation.getFunction());
11750                        }
11751                        if (relation.getEffectType() != null) {
11752                                relationElement.setEffectType(relation.getEffectType().name());
11753                        }
11754                        relationElement.setSqlHash(relation.getSqlHash());
11755                        relationElement.setSqlComment(relation.getSqlComment());
11756
11757                        if (relation.getProcedureId() != null) {
11758                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11759                        }
11760                        relationElement.setId(String.valueOf(relation.getId()));
11761
11762                        if (relation instanceof RecordSetRelationship) {
11763                                RecordSetRelationship recordCountRelation = (RecordSetRelationship) relation;
11764
11765                                Object targetElement = recordCountRelation.getTarget().getElement();
11766                                if (targetElement instanceof ResultColumn) {
11767                                        ResultColumn targetColumn = (ResultColumn) targetElement;
11768                                        targetColumn target = new targetColumn();
11769                                        target.setId(String.valueOf(targetColumn.getId()));
11770                                        target.setColumn(targetColumn.getName());
11771                                        target.setStruct(targetColumn.isStruct());
11772                                        target.setFunction(recordCountRelation.getAggregateFunction());
11773                                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
11774                                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
11775                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11776                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11777                                                                + convertCoordinate(targetColumn.getEndPosition()));
11778                                        }
11779                                        relationElement.setTarget(target);
11780                                } else if (targetElement instanceof TableColumn) {
11781                                        TableColumn targetColumn = (TableColumn) targetElement;
11782                                        targetColumn target = new targetColumn();
11783                                        target.setId(String.valueOf(targetColumn.getId()));
11784                                        target.setColumn(targetColumn.getName());
11785                                        target.setStruct(targetColumn.isStruct());
11786                                        target.setFunction(recordCountRelation.getAggregateFunction());
11787                                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
11788                                        target.setParent_name(getTableName(targetColumn.getTable()));
11789                                        if (recordCountRelation.getTarget() instanceof TableColumnRelationshipElement) {
11790                                                target.setParent_alias(
11791                                                                ((TableColumnRelationshipElement) recordCountRelation.getTarget()).getTableAlias());
11792                                        }
11793                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11794                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11795                                                                + convertCoordinate(targetColumn.getEndPosition()));
11796                                        }
11797                                        relationElement.setTarget(target);
11798                                } else if (targetElement instanceof ResultSetRelationRows) {
11799                                        ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement;
11800                                        targetColumn target = new targetColumn();
11801                                        target.setId(String.valueOf(targetColumn.getId()));
11802                                        target.setColumn(targetColumn.getName());
11803                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
11804                                        target.setParent_name(getResultSetName(targetColumn.getHolder()));
11805                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11806                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11807                                                                + convertCoordinate(targetColumn.getEndPosition()));
11808                                        }
11809                                        target.setSource("system");
11810                                        relationElement.setTarget(target);
11811                                } else {
11812                                        continue;
11813                                }
11814
11815                                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)recordCountRelation.getSources();
11816                                if (sourceElements.size() == 0) {
11817                                        continue;
11818                                }
11819
11820                                boolean append = false;
11821                                for (RelationshipElement<?> sourceItem: sourceElements) {
11822                                        Object sourceElement = sourceItem.getElement();
11823                                        if (sourceElement instanceof Table) {
11824                                                Table table = (Table) sourceElement;
11825                                                sourceColumn source = new sourceColumn();
11826                                                source.setSource_id(String.valueOf(table.getId()));
11827                                                source.setSource_name(getTableName(table));
11828                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
11829                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
11830                                                                        + convertCoordinate(table.getEndPosition()));
11831                                                }
11832                                                append = true;
11833                                                relationElement.addSource(source);
11834                                        } else if (sourceElement instanceof QueryTable) {
11835                                                QueryTable table = (QueryTable) sourceElement;
11836                                                sourceColumn source = new sourceColumn();
11837                                                source.setSource_id(String.valueOf(table.getId()));
11838                                                source.setSource_name(getResultSetName(table));
11839                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
11840                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
11841                                                                        + convertCoordinate(table.getEndPosition()));
11842                                                }
11843                                                append = true;
11844                                                relationElement.addSource(source);
11845                                        } else if (sourceElement instanceof TableRelationRows) {
11846                                                TableRelationRows relationRows = (TableRelationRows) sourceElement;
11847                                                sourceColumn source = new sourceColumn();
11848                                                source.setId(String.valueOf(relationRows.getId()));
11849                                                source.setColumn(relationRows.getName());
11850                                                source.setParent_id(String.valueOf(relationRows.getHolder().getId()));
11851                                                source.setParent_name(getTableName(relationRows.getHolder()));
11852                                                if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
11853                                                        source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
11854                                                                        + convertCoordinate(relationRows.getEndPosition()));
11855                                                }
11856                                                source.setSource("system");
11857                                                append = true;
11858                                                relationElement.addSource(source);
11859                                        } else if (sourceElement instanceof ResultSetRelationRows) {
11860                                                ResultSetRelationRows relationRows = (ResultSetRelationRows) sourceElement;
11861                                                sourceColumn source = new sourceColumn();
11862                                                source.setId(String.valueOf(relationRows.getId()));
11863                                                source.setColumn(relationRows.getName());
11864                                                source.setParent_id(String.valueOf(relationRows.getHolder().getId()));
11865                                                source.setParent_name(getResultSetName(relationRows.getHolder()));
11866                                                if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
11867                                                        source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
11868                                                                        + convertCoordinate(relationRows.getEndPosition()));
11869                                                }
11870                                                source.setSource("system");
11871                                                append = true;
11872                                                relationElement.addSource(source);
11873                                        } else if (sourceElement instanceof TableColumn) {
11874                                                TableColumn sourceColumn = (TableColumn) sourceElement;
11875                                                sourceColumn source = new sourceColumn();
11876                                                source.setId(String.valueOf(sourceColumn.getId()));
11877                                                source.setColumn(sourceColumn.getName());
11878                                                source.setStruct(sourceColumn.isStruct());
11879                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11880                                                source.setParent_name(getTableName(sourceColumn.getTable()));
11881                                                if (sourceItem instanceof TableColumnRelationshipElement) {
11882                                                        source.setParent_alias(
11883                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11884                                                }
11885                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11886                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11887                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11888                                                }
11889                                                append = true;
11890                                                relationElement.addSource(source);
11891                                        }
11892                                        if (sourceElement instanceof ResultColumn) {
11893                                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
11894                                                sourceColumn source = new sourceColumn();
11895                                                source.setId(String.valueOf(sourceColumn.getId()));
11896                                                source.setColumn(sourceColumn.getName());
11897                                                source.setStruct(sourceColumn.isStruct());
11898                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11899                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11900                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11901                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11902                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11903                                                }
11904                                                append = true;
11905                                                relationElement.addSource(source);
11906                                        }
11907                                }
11908
11909                                if (append)
11910                                        dataflow.getRelationships().add(relationElement);
11911                        }
11912                }
11913        }
11914
11915        private void appendCallRelation(dataflow dataflow, Relationship[] relations) {
11916                for (int i = 0; i < relations.length; i++) {
11917                        AbstractRelationship relation = (AbstractRelationship) relations[i];
11918                        relationship relationElement = new relationship();
11919                        relationElement.setType(relation.getRelationshipType().name());
11920                        if (relation.getFunction() != null) {
11921                                relationElement.setFunction(relation.getFunction());
11922                        }
11923                        if (relation.getEffectType() != null) {
11924                                relationElement.setEffectType(relation.getEffectType().name());
11925                        }
11926                        relationElement.setSqlHash(relation.getSqlHash());
11927                        relationElement.setSqlComment(relation.getSqlComment());
11928                        
11929                        if (relation.getProcedureId() != null) {
11930                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11931                        }
11932                        relationElement.setId(String.valueOf(relation.getId()));
11933
11934                        if (relation instanceof CallRelationship) {
11935                                CallRelationship callRelation = (CallRelationship) relation;
11936                                
11937                                if (callRelation.getCallObject() != null) {
11938                                        relationElement.setCallStmt(callRelation.getCallObject().toString());
11939                                        if (callRelation.getStartPosition() != null && callRelation.getEndPosition() != null) {
11940                                                relationElement.setCallCoordinate(convertCoordinate(callRelation.getStartPosition()) + ","
11941                                                                + convertCoordinate(callRelation.getEndPosition()));
11942                                        }
11943                                }
11944                                
11945                                if (Boolean.TRUE.equals(callRelation.getBuiltIn())) {
11946                                        relationElement.setBuiltIn(true);
11947                                }
11948                                Object targetElement = callRelation.getTarget().getElement();
11949                                if (targetElement instanceof Procedure) {
11950                                        Procedure procedure = (Procedure) targetElement;
11951                                        targetColumn target = new targetColumn();
11952                                        target.setId(String.valueOf(procedure.getId()));
11953                                        target.setName(getProcedureName(procedure));
11954                                        if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) {
11955                                                target.setCoordinate(convertCoordinate(procedure.getStartPosition()) + ","
11956                                                                + convertCoordinate(procedure.getEndPosition()));
11957                                        }
11958                                        String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase();
11959                                        if (clazz.indexOf("function") != -1) {
11960                                                target.setType("function");
11961                                        } else if (clazz.indexOf("trigger") != -1) {
11962                                                target.setType("trigger");
11963                                        } else if (clazz.indexOf("macro") != -1) {
11964                                                target.setType("macro");
11965                                        } else {
11966                                                target.setType("procedure");
11967                                        }
11968                                        relationElement.setCaller(target);
11969                                } else {
11970                                        continue;
11971                                }
11972
11973                                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)callRelation.getSources();
11974                                if (sourceElements.size() == 0) {
11975                                        continue;
11976                                }
11977
11978                                boolean append = false;
11979                                for (RelationshipElement<?> sourceItem: sourceElements) {
11980                                        Object sourceElement = sourceItem.getElement();
11981                                        if (sourceElement instanceof Procedure) {
11982                                                Procedure procedure = (Procedure) sourceElement;
11983                                                sourceColumn source = new sourceColumn();
11984                                                source.setId(String.valueOf(procedure.getId()));
11985                                                source.setName(getProcedureName(procedure));
11986                                                if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) {
11987                                                        source.setCoordinate(convertCoordinate(procedure.getStartPosition()) + ","
11988                                                                        + convertCoordinate(procedure.getEndPosition()));
11989                                                }
11990                                                String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase();
11991                                                if (clazz.indexOf("function") != -1) {
11992                                                        source.setType("function");
11993                                                } else if (clazz.indexOf("trigger") != -1) {
11994                                                        source.setType("trigger");
11995                                                } else if (clazz.indexOf("macro") != -1) {
11996                                                        source.setType("macro");
11997                                                } else {
11998                                                        source.setType("procedure");
11999                                                }
12000                                                append = true;
12001                                                relationElement.getCallees().add(source);
12002                                        } else if (sourceElement instanceof Function) {
12003                                                Function function = (Function) sourceElement;
12004                                                sourceColumn source = new sourceColumn();
12005                                                source.setId(String.valueOf(function.getId()));
12006                                                source.setName(getFunctionName(function.getFunctionObject()));
12007                                                if (function.getStartPosition() != null && function.getEndPosition() != null) {
12008                                                        source.setCoordinate(convertCoordinate(function.getStartPosition()) + ","
12009                                                                        + convertCoordinate(function.getEndPosition()));
12010                                                }
12011                                                source.setType("function");
12012                                                append = true;
12013                                                relationElement.getCallees().add(source);
12014                                        }
12015                                }
12016
12017                                if (append)
12018                                        dataflow.getRelationships().add(relationElement);
12019                        }
12020                }
12021        }
12022
12023        private void appendResultSets(dataflow dataflow) {
12024                Set<ResultSet> resultSets = modelManager.getResultSets(); 
12025                for (ResultSet resultSet: resultSets) {
12026                        appendResultSet(dataflow, resultSet);
12027                }
12028        }
12029
12030        private void appendResultSet(dataflow dataflow, ResultSet resultSetModel) {
12031                if (!appendResultSets.contains(resultSetModel)) {
12032                        appendResultSets.add(resultSetModel);
12033                } else {
12034                        return;
12035                }
12036
12037                table resultSetElement = new table();
12038                resultSetElement.setId(String.valueOf(resultSetModel.getId()));
12039                resultSetElement.setServer(resultSetModel.getServer());
12040                if (!SQLUtil.isEmpty(resultSetModel.getDatabase())) {
12041                        resultSetElement.setDatabase(resultSetModel.getDatabase());
12042                }
12043                if (!SQLUtil.isEmpty(resultSetModel.getSchema())) {
12044                        resultSetElement.setSchema(resultSetModel.getSchema());
12045                }
12046                resultSetElement.setName(getResultSetName(resultSetModel));
12047                resultSetElement.setType(getResultSetType(resultSetModel));
12048                // if ((ignoreRecordSet || simpleOutput) && resultSetModel.isTarget()) {
12049                resultSetElement.setIsTarget(String.valueOf(resultSetModel.isTarget()));
12050                // }
12051                resultSetElement.setIsDetermined(String.valueOf(resultSetModel.isDetermined()));
12052                if (resultSetModel.getStartPosition() != null && resultSetModel.getEndPosition() != null) {
12053                        resultSetElement.setCoordinate(convertCoordinate(resultSetModel.getStartPosition()) + ","
12054                                        + convertCoordinate(resultSetModel.getEndPosition()));
12055                }
12056                dataflow.getResultsets().add(resultSetElement);
12057
12058                List<ResultColumn> columns = resultSetModel.getColumns();
12059
12060                Map<String, Integer> columnCounts = new HashMap<String, Integer>();
12061                for (ResultColumn column : columns) {
12062                        String columnName = DlineageUtil.getIdentifierNormalColumnName(column.getName());
12063                        if (!columnCounts.containsKey(columnName)) {
12064                                columnCounts.put(columnName, 0);
12065                        }
12066                        columnCounts.put(columnName, columnCounts.get(columnName) + 1);
12067                        // if (column.hasStarLinkColumn()) {
12068                        // List<String> starLinkColumns = column.getStarLinkColumnNames();
12069                        // for (int k = 0; k < starLinkColumns.size(); k++) {
12070                        // columnName = starLinkColumns.get(k);
12071                        // if (!columnCounts.containsKey(columnName)) {
12072                        // columnCounts.put(columnName, 0);
12073                        // }
12074                        // columnCounts.put(columnName, columnCounts.get(columnName) + 1);
12075                        // }
12076                        // }
12077                }
12078
12079                for (int j = 0; j < columns.size(); j++) {
12080                        ResultColumn columnModel = columns.get(j);
12081                        if (columnModel.hasStarLinkColumn()) {
12082                                // List<String> starLinkColumns =
12083                                // columnModel.getStarLinkColumnNames();
12084                                // for (int k = 0; k < starLinkColumns.size(); k++) {
12085                                // column columnElement = new column();
12086                                // columnElement.setId( String.valueOf(columnModel.getId()) +
12087                                // "_" + k);
12088                                // String columnName = starLinkColumns.get(k);
12089                                // columnElement.setName(columnName);
12090                                // if(columnModel.isFunction()){
12091                                // columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
12092                                // }
12093                                // if (columnModel.getStartPosition() != null &&
12094                                // columnModel.getEndPosition() != null) {
12095                                // columnElement.setCoordinate(
12096                                // columnModel.getStartPosition() + "," +
12097                                // columnModel.getEndPosition());
12098                                // }
12099                                // String identifier = columnName;
12100                                // if(columnCounts.containsKey(identifier) &&
12101                                // columnCounts.get(identifier)>1){
12102                                // TObjectName column =
12103                                // columnModel.getStarLinkColumns().get(columnName).iterator().next();
12104                                // if(!SQLUtil.isEmpty(getQualifiedTable(column))){
12105                                // columnElement.setQualifiedTable(getQualifiedTable(column));
12106                                // }
12107                                // }
12108                                // resultSetElement.getColumns().add(columnElement);
12109                                // }
12110                                if (columnModel.isShowStar()) {
12111                                        column columnElement = new column();
12112                                        columnElement.setId(String.valueOf(columnModel.getId()));
12113                                        columnElement.setName(columnModel.getName());
12114                                        if (columnModel.isFunction()) {
12115                                                columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
12116                                        }
12117                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
12118                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12119                                                                + convertCoordinate(columnModel.getEndPosition()));
12120                                        }
12121
12122                                        String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName());
12123                                        if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) {
12124                                                String qualifiedTable = getQualifiedTable(columnModel);
12125                                                if (!SQLUtil.isEmpty(qualifiedTable)) {
12126                                                        columnElement.setQualifiedTable(qualifiedTable);
12127                                                }
12128                                        }
12129                                        resultSetElement.getColumns().add(columnElement);
12130                                }
12131                        } else {
12132                                column columnElement = new column();
12133                                columnElement.setId(String.valueOf(columnModel.getId()));
12134                                columnElement.setName(columnModel.getName());
12135                                if (columnModel.isFunction()) {
12136                                        columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
12137                                }
12138                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
12139                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12140                                                        + convertCoordinate(columnModel.getEndPosition()));
12141                                }
12142
12143                                String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName());
12144                                if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) {
12145                                        String qualifiedTable = getQualifiedTable(columnModel);
12146                                        if (!SQLUtil.isEmpty(qualifiedTable)) {
12147                                                columnElement.setQualifiedTable(qualifiedTable);
12148                                        }
12149                                }
12150                                resultSetElement.getColumns().add(columnElement);
12151                        }
12152                }
12153
12154                ResultSetRelationRows relationRows = resultSetModel.getRelationRows();
12155                if (relationRows.hasRelation()) {
12156                        column relationRowsElement = new column();
12157                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12158                        relationRowsElement.setName(relationRows.getName());
12159                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12160                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12161                                                + convertCoordinate(relationRows.getEndPosition()));
12162                        }
12163                        relationRowsElement.setSource("system");
12164                        resultSetElement.getColumns().add(relationRowsElement);
12165                }
12166        }
12167
12168        private String getQualifiedTable(ResultColumn columnModel) {
12169                if (columnModel.getColumnObject() instanceof TObjectName) {
12170                        return getQualifiedTable((TObjectName) columnModel.getColumnObject());
12171                }
12172                if (columnModel.getColumnObject() instanceof TResultColumn) {
12173                        TObjectName field = ((TResultColumn) columnModel.getColumnObject()).getFieldAttr();
12174                        if (field != null) {
12175                                return getQualifiedTable(field);
12176                        }
12177                }
12178                return null;
12179        }
12180
12181        private String getQualifiedTable(TObjectName column) {
12182                if (column == null)
12183                        return null;
12184                String[] splits = column.toString().split("\\.");
12185                if (splits.length > 1) {
12186                        return splits[splits.length - 2];
12187                }
12188                return null;
12189        }
12190
12191        private String getResultSetType(ResultSet resultSetModel) {
12192                if (resultSetModel instanceof QueryTable) {
12193                        QueryTable table = (QueryTable) resultSetModel;
12194                        if (table.getTableObject().getCTE() != null) {
12195                                return "with_cte";
12196                        }
12197                }
12198
12199                if (resultSetModel instanceof SelectSetResultSet) {
12200                        ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType();
12201                        return "select_" + type.name();
12202                }
12203
12204                if (resultSetModel instanceof SelectResultSet) {
12205                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) {
12206                                return "insert-select";
12207                        }
12208                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) {
12209                                return "update-select";
12210                        }
12211                }
12212
12213                if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) {
12214                        return "merge-update";
12215                }
12216
12217                if (resultSetModel.getGspObject() instanceof TOutputClause) {
12218                        return ResultSetType.output.name();
12219                }
12220
12221                if (resultSetModel.getGspObject() instanceof TMergeInsertClause) {
12222                        return "merge-insert";
12223                }
12224
12225                if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) {
12226                        return "update-set";
12227                }
12228
12229                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) {
12230                        return ResultSetType.array.name();
12231                }
12232
12233                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) {
12234                        return ResultSetType.struct.name();
12235                }
12236
12237                if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) {
12238                        return ResultSetType.function.name();
12239                }
12240
12241                if (resultSetModel.getGspObject() instanceof TAliasClause) {
12242                        return ResultSetType.alias.name();
12243                }
12244
12245                if (resultSetModel.getGspObject() instanceof TCursorDeclStmt) {
12246                        return ResultSetType.cursor.name();
12247                }
12248
12249                if (resultSetModel instanceof PivotedTable) {
12250                        if (((PivotedTable) resultSetModel).isUnpivoted()) {
12251                                return ResultSetType.unpivot_table.name();
12252                        }
12253                        return ResultSetType.pivot_table.name();
12254                }
12255
12256                return "select_list";
12257        }
12258
12259        private String getTableName(Table tableModel) {
12260                if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) {
12261                        return modelManager.DISPLAY_NAME.get(tableModel.getId());
12262                }
12263
12264                String tableName;
12265                if (tableModel.getFullName() != null && tableModel.getFullName().trim().length() > 0) {
12266                        return tableModel.getFullName();
12267                }
12268                if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) {
12269                        tableName = getResultSetWithId("RESULT_OF_" + tableModel.getAlias());
12270
12271                } else {
12272                        tableName = getResultSetDisplayId("RS");
12273                }
12274                modelManager.DISPLAY_NAME.put(tableModel.getId(), tableName);
12275                return tableName;
12276        }
12277
12278        private String getProcedureName(Procedure procedureModel) {
12279                if (modelManager.DISPLAY_NAME.containsKey(procedureModel.getId())) {
12280                        return modelManager.DISPLAY_NAME.get(procedureModel.getId());
12281                }
12282
12283                String procedureName = procedureModel.getFullName();
12284
12285                modelManager.DISPLAY_NAME.put(procedureModel.getId(), procedureName);
12286                return procedureName;
12287        }
12288
12289        private String getProcessName(Process processModel) {
12290                if (modelManager.DISPLAY_NAME.containsKey(processModel.getId())) {
12291                        return modelManager.DISPLAY_NAME.get(processModel.getId());
12292                } else {
12293                        if (processModel.getCustomType() != null) {
12294                                String name = processModel.getCustomType();
12295                                modelManager.DISPLAY_NAME.put(processModel.getId(), name);
12296                                return name;
12297                        }
12298                        String name = processModel.getType();
12299                        String procedureName = getProcedureParentName(processModel.getGspObject());
12300                        if (procedureName != null) {
12301                                name = getResultSetDisplayId(procedureName + " " + name);
12302                        } else {
12303                                name = getResultSetDisplayId("Query " + name);
12304                        }
12305                        modelManager.DISPLAY_NAME.put(processModel.getId(), name);
12306                        return name;
12307                }
12308        }
12309
12310        private String getDisplayIdByType(String type) {
12311                if (!modelManager.DISPLAY_ID.containsKey(type)) {
12312                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
12313                        return type + "-" + (option.getStartId() + 1);
12314                } else {
12315                        long id = modelManager.DISPLAY_ID.get(type);
12316                        modelManager.DISPLAY_ID.put(type, id + 1);
12317                        return type + "-" + (id + 1);
12318                }
12319        }
12320        
12321        private String getDisplayIdByTypeFromZero(String type) {
12322                if (!modelManager.DISPLAY_ID.containsKey(type)) {
12323                        modelManager.DISPLAY_ID.put(type, option.getStartId());
12324                        if(option.getStartId() == 0) {
12325                                return type;
12326                        }
12327                        return type + "-" + (option.getStartId() + 1);
12328                } else {
12329                        long id = modelManager.DISPLAY_ID.get(type);
12330                        modelManager.DISPLAY_ID.put(type, id + 1);
12331                        return type + "-" + (id + 1);
12332                }
12333        }
12334
12335        private String getConstantName(Table tableModel) {
12336                if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) {
12337                        return modelManager.DISPLAY_NAME.get(tableModel.getId());
12338                } else {
12339                        String name = getDisplayIdByType("SQL_CONSTANTS");
12340                        modelManager.DISPLAY_NAME.put(tableModel.getId(), name);
12341                        return name;
12342                }
12343        }
12344        
12345        private String getTempTableName(TTable table) {
12346                if (modelManager.DISPLAY_NAME.containsKey((long)System.identityHashCode(table))) {
12347                        return modelManager.DISPLAY_NAME.get((long)System.identityHashCode(table));
12348                } else {
12349                        String name = getDisplayIdByTypeFromZero(table.getName());
12350                        modelManager.DISPLAY_NAME.put((long)System.identityHashCode(table), name);
12351                        return name;
12352                }
12353        }
12354
12355        private String getResultSetName(ResultSet resultSetModel) {
12356
12357                if (modelManager.DISPLAY_NAME.containsKey(resultSetModel.getId())) {
12358                        return modelManager.DISPLAY_NAME.get(resultSetModel.getId());
12359                }
12360                
12361                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) {
12362                        String name = getResultSetDisplayId("ARRAY");
12363                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12364                        if(option.containsResultSetType(ResultSetType.array)) {
12365                                resultSetModel.setTarget(true);
12366                        }
12367                        return name;
12368                }
12369                
12370                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) {
12371                        String name = getResultSetDisplayId("STRUCT");
12372                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12373                        if(option.containsResultSetType(ResultSetType.struct)) {
12374                                resultSetModel.setTarget(true);
12375                        }
12376                        return name;
12377                }
12378
12379                if (resultSetModel instanceof QueryTable) {
12380                        QueryTable table = (QueryTable) resultSetModel;
12381                        if (table.getAlias() != null && table.getAlias().trim().length() > 0) {
12382                                String name = getResultSetWithId("RESULT_OF_" + table.getAlias().trim());
12383                                if (table.getTableObject().getCTE() != null) {
12384                                        name = getResultSetWithId("RESULT_OF_" + table.getTableObject().getCTE().getTableName().toString()
12385                                                        + "_" + table.getAlias().trim());
12386                                }
12387                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12388                                if(option.containsResultSetType(ResultSetType.result_of)) {
12389                                        resultSetModel.setTarget(true);
12390                                }
12391                                return name;
12392                        } else if (table.getTableObject().getCTE() != null) {
12393                                String name = getResultSetWithId("CTE-" + table.getTableObject().getCTE().getTableName().toString());
12394                                modelManager.DISPLAY_NAME.put(table.getId(), name);
12395                                if(option.containsResultSetType(ResultSetType.cte)) {
12396                                        resultSetModel.setTarget(true);
12397                                }
12398                                return name;
12399                        }
12400                }
12401
12402                if (resultSetModel instanceof SelectResultSet) {
12403                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) {
12404                                String name = getResultSetDisplayId("INSERT-SELECT");
12405                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12406                                if(option.containsResultSetType(ResultSetType.insert_select)) {
12407                                        resultSetModel.setTarget(true);
12408                                }
12409                                return name;
12410                        }
12411
12412                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) {
12413                                String name = getResultSetDisplayId("UPDATE-SELECT");
12414                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12415                                if(option.containsResultSetType(ResultSetType.update_select)) {
12416                                        resultSetModel.setTarget(true);
12417                                }
12418                                return name;
12419                        }
12420                }
12421
12422                if (resultSetModel instanceof SelectSetResultSet) {
12423                        ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType();
12424                        String name = getResultSetDisplayId("RESULT_OF_" + type.name().toUpperCase());
12425                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12426                        if(option.containsResultSetType(ResultSetType.result_of)) {
12427                                resultSetModel.setTarget(true);
12428                        }
12429                        return name;
12430                }
12431
12432                if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) {
12433                        String name = getResultSetDisplayId("MERGE-UPDATE");
12434                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12435                        if(option.containsResultSetType(ResultSetType.merge_update)) {
12436                                resultSetModel.setTarget(true);
12437                        }
12438                        return name;
12439                }
12440
12441                if (resultSetModel.getGspObject() instanceof TOutputClause) {
12442                        String name = getResultSetDisplayId("OUTPUT");
12443                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12444                        if(option.containsResultSetType(ResultSetType.output)) {
12445                                resultSetModel.setTarget(true);
12446                        }
12447                        return name;
12448                }
12449
12450                if (resultSetModel.getGspObject() instanceof TMergeInsertClause) {
12451                        String name = getResultSetDisplayId("MERGE-INSERT");
12452                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12453                        if(option.containsResultSetType(ResultSetType.merge_insert)) {
12454                                resultSetModel.setTarget(true);
12455                        }
12456                        return name;
12457                }
12458
12459                if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) {
12460                        String name = getResultSetDisplayId("UPDATE-SET");
12461                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12462                        if(option.containsResultSetType(ResultSetType.update_set)) {
12463                                resultSetModel.setTarget(true);
12464                        }
12465                        return name;
12466                }
12467
12468                if (resultSetModel.getGspObject() instanceof TCaseExpression) {
12469                        String name = ((Function) resultSetModel).getFunctionName();
12470                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12471                        if (option.containsResultSetType(ResultSetType.case_when) || option.containsResultSetType(ResultSetType.function)) {
12472                                resultSetModel.setTarget(true);
12473                        }
12474                        return name;
12475                }
12476                
12477                if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) {
12478                        String name = ((Function) resultSetModel).getFunctionName();
12479                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12480                        if(option.containsResultSetType(ResultSetType.function)) {
12481                                resultSetModel.setTarget(true);
12482                        }
12483                        return name;
12484                }
12485
12486                if (resultSetModel instanceof PivotedTable) {
12487                        String name = getResultSetDisplayId("PIVOT-TABLE");
12488                        if (((PivotedTable) resultSetModel).isUnpivoted()) {
12489                                name = getResultSetDisplayId("UNPIVOT-TABLE");
12490                                if(option.containsResultSetType(ResultSetType.unpivot_table)) {
12491                                        resultSetModel.setTarget(true);
12492                                }
12493                        }
12494                        else {
12495                                if(option.containsResultSetType(ResultSetType.pivot_table)) {
12496                                        resultSetModel.setTarget(true);
12497                                }
12498                        }
12499                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12500                        return name;
12501                }
12502
12503                if (resultSetModel instanceof Alias) {
12504                        String name = getResultSetDisplayId("ALIAS");
12505                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12506                        if(option.containsResultSetType(ResultSetType.alias)) {
12507                                resultSetModel.setTarget(true);
12508                        }
12509                        return name;
12510                }
12511
12512                String name = getResultSetDisplayId("RS");
12513                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
12514                if(option.containsResultSetType(ResultSetType.select_list)) {
12515                        resultSetModel.setTarget(true);
12516                }
12517                return name;
12518        }
12519
12520        private String getResultSetWithId(String type) {
12521                type = DlineageUtil.getIdentifierNormalTableName(type);
12522                if (!modelManager.DISPLAY_ID.containsKey(type)) {
12523                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
12524                        return type + "-" + (option.getStartId() + 1);
12525                } else {
12526                        long id = modelManager.DISPLAY_ID.get(type);
12527                        modelManager.DISPLAY_ID.put(type, id + 1);
12528                        return type + "-" + (id + 1);
12529                }
12530        }
12531
12532        private String getResultSetDisplayId(String type) {
12533                if (!modelManager.DISPLAY_ID.containsKey(type)) {
12534                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
12535                        return type + "-" + (option.getStartId() + 1);
12536                } else {
12537                        long id = modelManager.DISPLAY_ID.get(type);
12538                        modelManager.DISPLAY_ID.put(type, id + 1);
12539                        return type + "-" + (id + 1);
12540                }
12541        }
12542
12543        private void appendViews(dataflow dataflow) {
12544                List<TCustomSqlStatement> views = modelManager.getViews();
12545                for (int i = 0; i < views.size(); i++) {
12546                        Table viewModel = (Table) modelManager.getViewModel(views.get(i));
12547                        if (!tableIds.contains(viewModel.getId())) {
12548                                appendViewModel(dataflow, viewModel);
12549                                tableIds.add(viewModel.getId());
12550                        }
12551                }
12552
12553                List<TTable> tables = modelManager.getBaseTables();
12554                for (int i = 0; i < tables.size(); i++) {
12555                        Object model = modelManager.getModel(tables.get(i));
12556                        if (model instanceof Table) {
12557                                Table tableModel = (Table) model;
12558                                if (tableModel.isView()) {
12559                                        if (!tableIds.contains(tableModel.getId())) {
12560                                                appendViewModel(dataflow, tableModel);
12561                                                tableIds.add(tableModel.getId());
12562                                        }
12563                                }
12564                        }
12565                }
12566
12567                List<Table> tableNames = modelManager.getTablesByName();
12568                for (int i = 0; i < tableNames.size(); i++) {
12569                        Table tableModel = tableNames.get(i);
12570                        if (tableModel.isView()) {
12571                                if (!tableIds.contains(tableModel.getId())) {
12572                                        appendViewModel(dataflow, tableModel);
12573                                        tableIds.add(tableModel.getId());
12574                                }
12575                        }
12576                }
12577        }
12578
12579        private void appendViewModel(dataflow dataflow, Table viewModel) {
12580                table viewElement = new table();
12581                viewElement.setId(String.valueOf(viewModel.getId()));
12582                if (!SQLUtil.isEmpty(viewModel.getDatabase())) {
12583                        viewElement.setDatabase(viewModel.getDatabase());
12584                }
12585                if (!SQLUtil.isEmpty(viewModel.getSchema())) {
12586                        viewElement.setSchema(viewModel.getSchema());
12587                }
12588                viewElement.setServer(viewModel.getServer());
12589                viewElement.setName(viewModel.getName());
12590                viewElement.setType("view");
12591                viewElement.setStarStmt(viewModel.getStarStmt());
12592
12593                if(viewModel.isFromDDL()){
12594                        viewElement.setFromDDL(String.valueOf(viewModel.isFromDDL()));
12595                }
12596
12597                if (viewModel.getStartPosition() != null && viewModel.getEndPosition() != null) {
12598                        viewElement.setCoordinate(convertCoordinate(viewModel.getStartPosition()) + ","
12599                                        + convertCoordinate(viewModel.getEndPosition()));
12600                }
12601                if (viewModel.getProcesses() != null) {
12602                        List<String> processIds = new ArrayList<String>();
12603                        for (Process process : viewModel.getProcesses()) {
12604                                processIds.add(String.valueOf(process.getId()));
12605                        }
12606                        viewElement.setProcessIds(processIds);
12607                }
12608                dataflow.getViews().add(viewElement);
12609
12610                List<TableColumn> columns = viewModel.getColumns();
12611
12612                if (containStarColumn(columns)) {
12613                        for (TableColumn column : columns) {
12614                                if (column.getName().endsWith("*")) {
12615                                        for (TableColumn starElement : columns) {
12616                                                if (starElement == column) {
12617                                                        continue;
12618                                                }
12619                                                TObjectName columnObject = starElement.getColumnObject();
12620                                                column.bindStarLinkColumn(columnObject);
12621                                        }
12622                                        if (viewModel.isCreateTable()) {
12623                                                column.setShowStar(false);
12624                                        }
12625                                }
12626                        }
12627                }
12628
12629                for (int j = 0; j < columns.size(); j++) {
12630                        TableColumn columnModel = (TableColumn) columns.get(j);
12631                        if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn()) {
12632                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
12633                                for (int k = 0; k < starLinkColumnList.size(); k++) {
12634                                        column columnElement = new column();
12635                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
12636                                        String columnName = starLinkColumnList.get(k);
12637                                        if (containStarColumn(columns, columnName)) {
12638                                                continue;
12639                                        }
12640                                        columnElement.setName(columnName);
12641                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
12642                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12643                                                                + convertCoordinate(columnModel.getEndPosition()));
12644                                        }
12645                                        viewElement.getColumns().add(columnElement);
12646                                }
12647
12648                                if (columnModel.isShowStar()) {
12649                                        column columnElement = new column();
12650                                        columnElement.setId(String.valueOf(columnModel.getId()));
12651                                        columnElement.setName(columnModel.getName());
12652                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
12653                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12654                                                                + convertCoordinate(columnModel.getEndPosition()));
12655                                        }
12656                                        viewElement.getColumns().add(columnElement);
12657                                }
12658
12659                        } else {
12660                                column columnElement = new column();
12661                                columnElement.setId(String.valueOf(columnModel.getId()));
12662                                columnElement.setName(columnModel.getName());
12663                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
12664                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12665                                                        + convertCoordinate(columnModel.getEndPosition()));
12666                                }
12667                                if(columnModel.isPseduo()) {
12668                                        columnElement.setSource("system");
12669                                }
12670                                viewElement.getColumns().add(columnElement);
12671                        }
12672                }
12673
12674                TableRelationRows relationRows = viewModel.getRelationRows();
12675                if (relationRows.hasRelation()) {
12676                        column relationRowsElement = new column();
12677                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12678                        relationRowsElement.setName(relationRows.getName());
12679                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12680                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12681                                                + convertCoordinate(relationRows.getEndPosition()));
12682                        }
12683                        relationRowsElement.setSource("system");
12684                        viewElement.getColumns().add(relationRowsElement);
12685                }
12686        }
12687
12688        private void appendStreamModel(dataflow dataflow, Table streamModel) {
12689                table streamElement = new table();
12690                streamElement.setId(String.valueOf(streamModel.getId()));
12691                if (!SQLUtil.isEmpty(streamModel.getDatabase())) {
12692                        streamElement.setDatabase(streamModel.getDatabase());
12693                }
12694                if (!SQLUtil.isEmpty(streamModel.getSchema())) {
12695                        streamElement.setSchema(streamModel.getSchema());
12696                }
12697                streamElement.setServer(streamModel.getServer());
12698                streamElement.setName(streamModel.getName());
12699                streamElement.setType("stream");
12700                if (streamModel.getFileType() != null) {
12701                        streamElement.setFileType(SQLUtil.trimColumnStringQuote(streamModel.getFileType()));
12702                }
12703
12704                if (streamModel.getStartPosition() != null && streamModel.getEndPosition() != null) {
12705                        streamElement.setCoordinate(convertCoordinate(streamModel.getStartPosition()) + ","
12706                                        + convertCoordinate(streamModel.getEndPosition()));
12707                }
12708
12709                if (streamModel.getProcesses() != null) {
12710                        List<String> processIds = new ArrayList<String>();
12711                        for (Process process : streamModel.getProcesses()) {
12712                                processIds.add(String.valueOf(process.getId()));
12713                        }
12714                        streamElement.setProcessIds(processIds);
12715                }
12716                dataflow.getStreams().add(streamElement);
12717
12718                List<TableColumn> columns = streamModel.getColumns();
12719
12720                for (int j = 0; j < columns.size(); j++) {
12721                        TableColumn columnModel = (TableColumn) columns.get(j);
12722                        column columnElement = new column();
12723                        columnElement.setId(String.valueOf(columnModel.getId()));
12724                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
12725                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12726                                        + convertCoordinate(columnModel.getEndPosition()));
12727                        streamElement.getColumns().add(columnElement);
12728                }
12729
12730                TableRelationRows relationRows = streamModel.getRelationRows();
12731                if (relationRows.hasRelation()) {
12732                        column relationRowsElement = new column();
12733                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12734                        relationRowsElement.setName(relationRows.getName());
12735                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12736                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12737                                                + convertCoordinate(relationRows.getEndPosition()));
12738                        }
12739                        relationRowsElement.setSource("system");
12740                        streamElement.getColumns().add(relationRowsElement);
12741                }
12742        }
12743
12744        private void appendStageModel(dataflow dataflow, Table stageModel) {
12745                table stageElement = new table();
12746                stageElement.setId(String.valueOf(stageModel.getId()));
12747                if (!SQLUtil.isEmpty(stageModel.getDatabase())) {
12748                        stageElement.setDatabase(stageModel.getDatabase());
12749                }
12750                if (!SQLUtil.isEmpty(stageModel.getSchema())) {
12751                        stageElement.setSchema(stageModel.getSchema());
12752                }
12753                stageElement.setServer(stageModel.getServer());
12754                stageElement.setName(stageModel.getName());
12755                stageElement.setType("stage");
12756                stageElement.setLocation(stageModel.getLocation());
12757                if (stageModel.getFileType() != null) {
12758                        stageElement.setFileType(SQLUtil.trimColumnStringQuote(stageModel.getFileType()));
12759                }
12760
12761                if (stageModel.getStartPosition() != null && stageModel.getEndPosition() != null) {
12762                        stageElement.setCoordinate(convertCoordinate(stageModel.getStartPosition()) + ","
12763                                        + convertCoordinate(stageModel.getEndPosition()));
12764                }
12765
12766                if (stageModel.getProcesses() != null) {
12767                        List<String> processIds = new ArrayList<String>();
12768                        for (Process process : stageModel.getProcesses()) {
12769                                processIds.add(String.valueOf(process.getId()));
12770                        }
12771                        stageElement.setProcessIds(processIds);
12772                }
12773                dataflow.getStages().add(stageElement);
12774
12775                List<TableColumn> columns = stageModel.getColumns();
12776
12777                for (int j = 0; j < columns.size(); j++) {
12778                        TableColumn columnModel = (TableColumn) columns.get(j);
12779                        column columnElement = new column();
12780                        columnElement.setId(String.valueOf(columnModel.getId()));
12781                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
12782                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12783                                        + convertCoordinate(columnModel.getEndPosition()));
12784                        stageElement.getColumns().add(columnElement);
12785                }
12786
12787                TableRelationRows relationRows = stageModel.getRelationRows();
12788                if (relationRows.hasRelation()) {
12789                        column relationRowsElement = new column();
12790                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12791                        relationRowsElement.setName(relationRows.getName());
12792                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12793                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12794                                                + convertCoordinate(relationRows.getEndPosition()));
12795                        }
12796                        relationRowsElement.setSource("system");
12797                        stageElement.getColumns().add(relationRowsElement);
12798                }
12799        }
12800
12801        private void appendSequenceModel(dataflow dataflow, Table sequenceModel) {
12802                table sequenceElement = new table();
12803                sequenceElement.setId(String.valueOf(sequenceModel.getId()));
12804                if (!SQLUtil.isEmpty(sequenceModel.getDatabase())) {
12805                        sequenceElement.setDatabase(sequenceModel.getDatabase());
12806                }
12807                if (!SQLUtil.isEmpty(sequenceModel.getSchema())) {
12808                        sequenceElement.setSchema(sequenceModel.getSchema());
12809                }
12810                sequenceElement.setServer(sequenceModel.getServer());
12811                sequenceElement.setName(sequenceModel.getName());
12812                sequenceElement.setType("sequence");
12813                sequenceElement.setLocation(sequenceModel.getLocation());
12814                if (sequenceModel.getFileType() != null) {
12815                        sequenceElement.setFileType(SQLUtil.trimColumnStringQuote(sequenceModel.getFileType()));
12816                }
12817
12818                if (sequenceModel.getStartPosition() != null && sequenceModel.getEndPosition() != null) {
12819                        sequenceElement.setCoordinate(convertCoordinate(sequenceModel.getStartPosition()) + ","
12820                                        + convertCoordinate(sequenceModel.getEndPosition()));
12821                }
12822
12823                if (sequenceModel.getProcesses() != null) {
12824                        List<String> processIds = new ArrayList<String>();
12825                        for (Process process : sequenceModel.getProcesses()) {
12826                                processIds.add(String.valueOf(process.getId()));
12827                        }
12828                        sequenceElement.setProcessIds(processIds);
12829                }
12830                dataflow.getSequences().add(sequenceElement);
12831
12832                List<TableColumn> columns = sequenceModel.getColumns();
12833
12834                for (int j = 0; j < columns.size(); j++) {
12835                        TableColumn columnModel = (TableColumn) columns.get(j);
12836                        column columnElement = new column();
12837                        columnElement.setId(String.valueOf(columnModel.getId()));
12838                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
12839                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12840                                        + convertCoordinate(columnModel.getEndPosition()));
12841                        sequenceElement.getColumns().add(columnElement);
12842                }
12843
12844                TableRelationRows relationRows = sequenceModel.getRelationRows();
12845                if (relationRows.hasRelation()) {
12846                        column relationRowsElement = new column();
12847                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12848                        relationRowsElement.setName(relationRows.getName());
12849                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12850                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12851                                                + convertCoordinate(relationRows.getEndPosition()));
12852                        }
12853                        relationRowsElement.setSource("system");
12854                        sequenceElement.getColumns().add(relationRowsElement);
12855                }
12856        }
12857
12858        private void appendDataSourceModel(dataflow dataflow, Table datasourceModel) {
12859                table datasourceElement = new table();
12860                datasourceElement.setId(String.valueOf(datasourceModel.getId()));
12861                if (!SQLUtil.isEmpty(datasourceModel.getDatabase())) {
12862                        datasourceElement.setDatabase(datasourceModel.getDatabase());
12863                }
12864                if (!SQLUtil.isEmpty(datasourceModel.getSchema())) {
12865                        datasourceElement.setSchema(datasourceModel.getSchema());
12866                }
12867                datasourceElement.setServer(datasourceModel.getServer());
12868                datasourceElement.setName(datasourceModel.getName());
12869                datasourceElement.setType("datasource");
12870                datasourceElement.setLocation(datasourceModel.getLocation());
12871                if (datasourceModel.getFileType() != null) {
12872                        datasourceElement.setFileType(SQLUtil.trimColumnStringQuote(datasourceModel.getFileType()));
12873                }
12874
12875                if (datasourceModel.getStartPosition() != null && datasourceModel.getEndPosition() != null) {
12876                        datasourceElement.setCoordinate(convertCoordinate(datasourceModel.getStartPosition()) + ","
12877                                        + convertCoordinate(datasourceModel.getEndPosition()));
12878                }
12879
12880                if (datasourceModel.getProcesses() != null) {
12881                        List<String> processIds = new ArrayList<String>();
12882                        for (Process process : datasourceModel.getProcesses()) {
12883                                processIds.add(String.valueOf(process.getId()));
12884                        }
12885                        datasourceElement.setProcessIds(processIds);
12886                }
12887                dataflow.getDatasources().add(datasourceElement);
12888
12889                List<TableColumn> columns = datasourceModel.getColumns();
12890
12891                for (int j = 0; j < columns.size(); j++) {
12892                        TableColumn columnModel = (TableColumn) columns.get(j);
12893                        column columnElement = new column();
12894                        columnElement.setId(String.valueOf(columnModel.getId()));
12895                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
12896                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12897                                        + convertCoordinate(columnModel.getEndPosition()));
12898                        datasourceElement.getColumns().add(columnElement);
12899                }
12900
12901                TableRelationRows relationRows = datasourceModel.getRelationRows();
12902                if (relationRows.hasRelation()) {
12903                        column relationRowsElement = new column();
12904                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12905                        relationRowsElement.setName(relationRows.getName());
12906                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12907                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12908                                                + convertCoordinate(relationRows.getEndPosition()));
12909                        }
12910                        relationRowsElement.setSource("system");
12911                        datasourceElement.getColumns().add(relationRowsElement);
12912                }
12913        }
12914
12915        private void appendDatabaseModel(dataflow dataflow, Table databaseModel) {
12916                table databaseElement = new table();
12917                databaseElement.setId(String.valueOf(databaseModel.getId()));
12918                if (!SQLUtil.isEmpty(databaseModel.getDatabase())) {
12919                        databaseElement.setDatabase(databaseModel.getDatabase());
12920                }
12921                if (!SQLUtil.isEmpty(databaseModel.getSchema())) {
12922                        databaseElement.setSchema(databaseModel.getSchema());
12923                }
12924                databaseElement.setServer(databaseModel.getServer());
12925                databaseElement.setName(databaseModel.getName());
12926                databaseElement.setType("database");
12927                if (databaseModel.getFileType() != null) {
12928                        databaseElement.setFileType(SQLUtil.trimColumnStringQuote(databaseModel.getFileType()));
12929                }
12930
12931                if (databaseModel.getStartPosition() != null && databaseModel.getEndPosition() != null) {
12932                        databaseElement.setCoordinate(convertCoordinate(databaseModel.getStartPosition()) + ","
12933                                        + convertCoordinate(databaseModel.getEndPosition()));
12934                }
12935
12936                if (databaseModel.getProcesses() != null) {
12937                        List<String> processIds = new ArrayList<String>();
12938                        for (Process process : databaseModel.getProcesses()) {
12939                                processIds.add(String.valueOf(process.getId()));
12940                        }
12941                        databaseElement.setProcessIds(processIds);
12942                }
12943                dataflow.getDatabases().add(databaseElement);
12944
12945                List<TableColumn> columns = databaseModel.getColumns();
12946
12947                for (int j = 0; j < columns.size(); j++) {
12948                        TableColumn columnModel = (TableColumn) columns.get(j);
12949                        column columnElement = new column();
12950                        columnElement.setId(String.valueOf(columnModel.getId()));
12951                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
12952                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
12953                                        + convertCoordinate(columnModel.getEndPosition()));
12954                        databaseElement.getColumns().add(columnElement);
12955                }
12956
12957                TableRelationRows relationRows = databaseModel.getRelationRows();
12958                if (relationRows.hasRelation()) {
12959                        column relationRowsElement = new column();
12960                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
12961                        relationRowsElement.setName(relationRows.getName());
12962                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12963                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12964                                                + convertCoordinate(relationRows.getEndPosition()));
12965                        }
12966                        relationRowsElement.setSource("system");
12967                        databaseElement.getColumns().add(relationRowsElement);
12968                }
12969        }
12970
12971        private void appendSchemaModel(dataflow dataflow, Table schemaModel) {
12972                table schemaElement = new table();
12973                schemaElement.setId(String.valueOf(schemaModel.getId()));
12974                if (!SQLUtil.isEmpty(schemaModel.getDatabase())) {
12975                        schemaElement.setDatabase(schemaModel.getDatabase());
12976                }
12977                if (!SQLUtil.isEmpty(schemaModel.getSchema())) {
12978                        schemaElement.setSchema(schemaModel.getSchema());
12979                }
12980                schemaElement.setServer(schemaModel.getServer());
12981                schemaElement.setName(schemaModel.getName());
12982                schemaElement.setType("schema");
12983                if (schemaModel.getFileType() != null) {
12984                        schemaElement.setFileType(SQLUtil.trimColumnStringQuote(schemaModel.getFileType()));
12985                }
12986
12987                if (schemaModel.getStartPosition() != null && schemaModel.getEndPosition() != null) {
12988                        schemaElement.setCoordinate(convertCoordinate(schemaModel.getStartPosition()) + ","
12989                                        + convertCoordinate(schemaModel.getEndPosition()));
12990                }
12991
12992                if (schemaModel.getProcesses() != null) {
12993                        List<String> processIds = new ArrayList<String>();
12994                        for (Process process : schemaModel.getProcesses()) {
12995                                processIds.add(String.valueOf(process.getId()));
12996                        }
12997                        schemaElement.setProcessIds(processIds);
12998                }
12999                dataflow.getSchemas().add(schemaElement);
13000
13001                List<TableColumn> columns = schemaModel.getColumns();
13002
13003                for (int j = 0; j < columns.size(); j++) {
13004                        TableColumn columnModel = (TableColumn) columns.get(j);
13005                        column columnElement = new column();
13006                        columnElement.setId(String.valueOf(columnModel.getId()));
13007                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13008                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13009                                        + convertCoordinate(columnModel.getEndPosition()));
13010                        schemaElement.getColumns().add(columnElement);
13011                }
13012
13013                TableRelationRows relationRows = schemaModel.getRelationRows();
13014                if (relationRows.hasRelation()) {
13015                        column relationRowsElement = new column();
13016                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13017                        relationRowsElement.setName(relationRows.getName());
13018                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13019                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13020                                                + convertCoordinate(relationRows.getEndPosition()));
13021                        }
13022                        relationRowsElement.setSource("system");
13023                        schemaElement.getColumns().add(relationRowsElement);
13024                }
13025        }
13026
13027        private void appendPathModel(dataflow dataflow, Table pathModel) {
13028                table pathElement = new table();
13029                pathElement.setId(String.valueOf(pathModel.getId()));
13030                if (!SQLUtil.isEmpty(pathModel.getDatabase())) {
13031                        pathElement.setDatabase(pathModel.getDatabase());
13032                }
13033                if (!SQLUtil.isEmpty(pathModel.getSchema())) {
13034                        pathElement.setSchema(pathModel.getSchema());
13035                }
13036                pathElement.setServer(pathModel.getServer());
13037                pathElement.setName(pathModel.getName());
13038                pathElement.setType("path");
13039                if (pathModel.getFileFormat() != null) {
13040                        pathElement.setFileFormat(SQLUtil.trimColumnStringQuote(pathModel.getFileFormat()));
13041                }
13042
13043                if (pathModel.getStartPosition() != null && pathModel.getEndPosition() != null) {
13044                        pathElement.setCoordinate(convertCoordinate(pathModel.getStartPosition()) + ","
13045                                        + convertCoordinate(pathModel.getEndPosition()));
13046                }
13047
13048                if (pathModel.getProcesses() != null) {
13049                        List<String> processIds = new ArrayList<String>();
13050                        for (Process process : pathModel.getProcesses()) {
13051                                processIds.add(String.valueOf(process.getId()));
13052                        }
13053                        pathElement.setProcessIds(processIds);
13054                }
13055
13056                pathElement.setUri(pathModel.getName());
13057
13058                dataflow.getPaths().add(pathElement);
13059
13060                List<TableColumn> columns = pathModel.getColumns();
13061
13062                for (int j = 0; j < columns.size(); j++) {
13063                        TableColumn columnModel = (TableColumn) columns.get(j);
13064                        column columnElement = new column();
13065                        columnElement.setId(String.valueOf(columnModel.getId()));
13066                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13067                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13068                                        + convertCoordinate(columnModel.getEndPosition()));
13069                        pathElement.getColumns().add(columnElement);
13070                }
13071
13072                TableRelationRows relationRows = pathModel.getRelationRows();
13073                if (relationRows.hasRelation()) {
13074                        column relationRowsElement = new column();
13075                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13076                        relationRowsElement.setName(relationRows.getName());
13077                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13078                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13079                                                + convertCoordinate(relationRows.getEndPosition()));
13080                        }
13081                        relationRowsElement.setSource("system");
13082                        pathElement.getColumns().add(relationRowsElement);
13083                }
13084        }
13085
13086        private void appendVariableModel(dataflow dataflow, Table variableModel) {
13087                table variableElement = new table();
13088                variableElement.setId(String.valueOf(variableModel.getId()));
13089                if (!SQLUtil.isEmpty(variableModel.getDatabase())) {
13090                        variableElement.setDatabase(variableModel.getDatabase());
13091                }
13092                if (!SQLUtil.isEmpty(variableModel.getSchema())) {
13093                        variableElement.setSchema(variableModel.getSchema());
13094                }
13095                variableElement.setServer(variableModel.getServer());
13096                variableElement.setName(variableModel.getName());
13097                variableElement.setType("variable");
13098                variableElement.setParent(variableModel.getParent());
13099                if (variableModel.getSubType() != null) {
13100                        variableElement.setSubType(variableModel.getSubType().name());
13101                }
13102
13103                if (variableModel.getStartPosition() != null && variableModel.getEndPosition() != null) {
13104                        variableElement.setCoordinate(convertCoordinate(variableModel.getStartPosition()) + ","
13105                                        + convertCoordinate(variableModel.getEndPosition()));
13106                }
13107                dataflow.getVariables().add(variableElement);
13108
13109                List<TableColumn> columns = variableModel.getColumns();
13110
13111                if (containStarColumn(columns)) {
13112                        for (TableColumn column : columns) {
13113                                if (column.getName().endsWith("*")) {
13114                                        for (TableColumn starElement : columns) {
13115                                                if (starElement == column) {
13116                                                        continue;
13117                                                }
13118                                                TObjectName columnObject = starElement.getColumnObject();
13119                                                column.bindStarLinkColumn(columnObject);
13120                                        }
13121//                                      column.setShowStar(false);
13122                                }
13123                        }
13124                }
13125
13126                for (int j = 0; j < columns.size(); j++) {
13127                        TableColumn columnModel = columns.get(j);
13128                        if (columnModel.hasStarLinkColumn()) {
13129                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
13130                                for (int k = 0; k < starLinkColumnList.size(); k++) {
13131                                        column columnElement = new column();
13132                                        columnElement.setId(columnModel.getId() + "_" + k);
13133                                        String columnName = starLinkColumnList.get(k);
13134                                        if (containStarColumn(columns, columnName)) {
13135                                                continue;
13136                                        }
13137                                        columnElement.setName(columnName);
13138                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13139                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13140                                                                + convertCoordinate(columnModel.getEndPosition()));
13141                                        }
13142                                        variableElement.getColumns().add(columnElement);
13143                                }
13144
13145                                if (columnModel.isShowStar()) {
13146                                        column columnElement = new column();
13147                                        columnElement.setId(String.valueOf(columnModel.getId()));
13148                                        columnElement.setName(columnModel.getName());
13149                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13150                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13151                                                                + convertCoordinate(columnModel.getEndPosition()));
13152                                        }
13153                                        variableElement.getColumns().add(columnElement);
13154                                }
13155
13156                        } else {
13157                                column columnElement = new column();
13158                                columnElement.setId(String.valueOf(columnModel.getId()));
13159                                columnElement.setName(columnModel.getName());
13160                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13161                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13162                                                        + convertCoordinate(columnModel.getEndPosition()));
13163                                }
13164                                variableElement.getColumns().add(columnElement);
13165                        }
13166                }
13167
13168                TableRelationRows relationRows = variableModel.getRelationRows();
13169                if (relationRows.hasRelation()) {
13170                        column relationRowsElement = new column();
13171                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13172                        relationRowsElement.setName(relationRows.getName());
13173                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13174                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13175                                                + convertCoordinate(relationRows.getEndPosition()));
13176                        }
13177                        relationRowsElement.setSource("system");
13178                        variableElement.getColumns().add(relationRowsElement);
13179                }
13180        }
13181
13182        private void appendCursorModel(dataflow dataflow, Table cursorModel) {
13183                table cursorElement = new table();
13184                cursorElement.setId(String.valueOf(cursorModel.getId()));
13185                if (!SQLUtil.isEmpty(cursorModel.getDatabase())) {
13186                        cursorElement.setDatabase(cursorModel.getDatabase());
13187                }
13188                if (!SQLUtil.isEmpty(cursorModel.getSchema())) {
13189                        cursorElement.setSchema(cursorModel.getSchema());
13190                }
13191                cursorElement.setServer(cursorModel.getServer());
13192                cursorElement.setName(cursorModel.getName());
13193                cursorElement.setType("variable");
13194                if (cursorElement.getSubType() != null) {
13195                        cursorElement.setSubType(cursorModel.getSubType().name());
13196                }
13197
13198                if (cursorModel.getStartPosition() != null && cursorModel.getEndPosition() != null) {
13199                        cursorElement.setCoordinate(convertCoordinate(cursorModel.getStartPosition()) + ","
13200                                        + convertCoordinate(cursorModel.getEndPosition()));
13201                }
13202                dataflow.getVariables().add(cursorElement);
13203
13204                List<TableColumn> columns = cursorModel.getColumns();
13205
13206                if (containStarColumn(columns)) {
13207                        for (TableColumn column : columns) {
13208                                if (column.getName().endsWith("*")) {
13209                                        for (TableColumn starElement : columns) {
13210                                                if (starElement == column) {
13211                                                        continue;
13212                                                }
13213                                                TObjectName columnObject = starElement.getColumnObject();
13214                                                column.bindStarLinkColumn(columnObject);
13215                                        }
13216                                        column.setShowStar(false);
13217                                }
13218                        }
13219                }
13220
13221                for (int j = 0; j < columns.size(); j++) {
13222                        TableColumn columnModel = (TableColumn) columns.get(j);
13223                        if (columnModel.hasStarLinkColumn()) {
13224                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
13225                                for (int k = 0; k < starLinkColumnList.size(); k++) {
13226                                        column columnElement = new column();
13227                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
13228                                        String columnName = starLinkColumnList.get(k);
13229                                        if (containStarColumn(columns, columnName)) {
13230                                                continue;
13231                                        }
13232                                        columnElement.setName(columnName);
13233                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13234                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13235                                                                + convertCoordinate(columnModel.getEndPosition()));
13236                                        }
13237                                        cursorElement.getColumns().add(columnElement);
13238                                }
13239
13240                                if (columnModel.isShowStar()) {
13241                                        column columnElement = new column();
13242                                        columnElement.setId(String.valueOf(columnModel.getId()));
13243                                        columnElement.setName(columnModel.getName());
13244                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13245                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13246                                                                + convertCoordinate(columnModel.getEndPosition()));
13247                                        }
13248                                        cursorElement.getColumns().add(columnElement);
13249                                }
13250
13251                        } else {
13252                                column columnElement = new column();
13253                                columnElement.setId(String.valueOf(columnModel.getId()));
13254                                columnElement.setName(columnModel.getName());
13255                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13256                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13257                                                        + convertCoordinate(columnModel.getEndPosition()));
13258                                }
13259                                cursorElement.getColumns().add(columnElement);
13260                        }
13261                }
13262
13263                TableRelationRows relationRows = cursorModel.getRelationRows();
13264                if (relationRows.hasRelation()) {
13265                        column relationRowsElement = new column();
13266                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13267                        relationRowsElement.setName(relationRows.getName());
13268                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13269                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13270                                                + convertCoordinate(relationRows.getEndPosition()));
13271                        }
13272                        relationRowsElement.setSource("system");
13273                        cursorElement.getColumns().add(relationRowsElement);
13274                }
13275        }
13276
13277        private void appendErrors(dataflow dataflow) {
13278                List<ErrorInfo> errorInfos = this.getErrorMessages();
13279                if (metadataErrors != null) {
13280                        for (int i = 0; i < metadataErrors.size(); i++) {
13281                                errorInfos.add(i, metadataErrors.get(i));
13282                        }
13283                }
13284
13285                for (int i = 0; i < errorInfos.size(); ++i) {
13286                        ErrorInfo errorInfo = errorInfos.get(i);
13287                        error error = new error();
13288                        if (!SQLUtil.isEmpty(errorInfo.getErrorMessage())) {
13289                                error.setErrorMessage(errorInfo.getErrorMessage());
13290                        }
13291                        if (!SQLUtil.isEmpty(errorInfo.getErrorType())) {
13292                                error.setErrorType(errorInfo.getErrorType());
13293                        }
13294                        if (errorInfo.getStartPosition() != null && errorInfo.getEndPosition() != null) {
13295                                error.setCoordinate(convertCoordinate(errorInfo.getStartPosition()) + ","
13296                                                + convertCoordinate(errorInfo.getEndPosition()));
13297                        }
13298                        if (!SQLUtil.isEmpty(errorInfo.getFileName())) {
13299                                error.setFile(errorInfo.getFileName());
13300                        }
13301                        if (errorInfo.getOriginStartPosition() != null && errorInfo.getOriginEndPosition() != null) {
13302                                error.setOriginCoordinate(errorInfo.getOriginStartPosition() + "," + errorInfo.getOriginEndPosition());
13303                        }
13304                        dataflow.getErrors().add(error);
13305                }
13306        }
13307
13308        private void appendOraclePackages(dataflow dataflow) {
13309                List<OraclePackage> packages = this.modelManager.getOraclePackageModels();
13310
13311                for (int i = 0; i < packages.size(); ++i) {
13312                        OraclePackage model = packages.get(i);
13313                        oraclePackage oraclePackage = new oraclePackage();
13314                        oraclePackage.setId(String.valueOf(model.getId()));
13315                        if (!SQLUtil.isEmpty(model.getDatabase())) {
13316                                oraclePackage.setDatabase(model.getDatabase());
13317                        }
13318                        if (!SQLUtil.isEmpty(model.getSchema())) {
13319                                oraclePackage.setSchema(model.getSchema());
13320                        }
13321                        oraclePackage.setServer(model.getServer());
13322                        oraclePackage.setName(model.getName());
13323                        if (model.getType() != null) {
13324                                oraclePackage.setType(model.getType().name().replace("sst", ""));
13325                        }
13326                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
13327                                oraclePackage.setCoordinate(
13328                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
13329                        }
13330
13331                        dataflow.getPackages().add(oraclePackage);
13332
13333                        List<Argument> arguments = model.getArguments();
13334
13335                        for (int j = 0; j < arguments.size(); ++j) {
13336                                Argument argumentModel = (Argument) arguments.get(j);
13337                                argument argumentElement = new argument();
13338                                argumentElement.setId(String.valueOf(argumentModel.getId()));
13339                                argumentElement.setName(argumentModel.getName());
13340                                if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
13341                                        argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
13342                                                        + convertCoordinate(argumentModel.getEndPosition()));
13343                                }
13344
13345                                argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
13346                                argumentElement.setInout(argumentModel.getMode().name());
13347                                oraclePackage.getArguments().add(argumentElement);
13348                        }
13349
13350                        for (int j = 0; j < model.getProcedures().size(); j++) {
13351                                Procedure procedureModel = model.getProcedures().get(j);
13352                                procedure procedure = new procedure();
13353                                procedure.setId(String.valueOf(procedureModel.getId()));
13354                                if (!SQLUtil.isEmpty(procedureModel.getDatabase())) {
13355                                        procedure.setDatabase(procedureModel.getDatabase());
13356                                }
13357                                if (!SQLUtil.isEmpty(procedureModel.getSchema())) {
13358                                        procedure.setSchema(procedureModel.getSchema());
13359                                }
13360                                procedure.setServer(procedureModel.getServer());
13361                                procedure.setName(procedureModel.getName());
13362                                if (procedureModel.getType() != null) {
13363                                        procedure.setType(procedureModel.getType().name().replace("sst", ""));
13364                                }
13365                                if (procedureModel.getStartPosition() != null && procedureModel.getEndPosition() != null) {
13366                                        procedure.setCoordinate(convertCoordinate(procedureModel.getStartPosition()) + ","
13367                                                        + convertCoordinate(procedureModel.getEndPosition()));
13368                                }
13369
13370                                oraclePackage.getProcedures().add(procedure);
13371
13372                                List<Argument> procedureArguments = procedureModel.getArguments();
13373
13374                                for (int k = 0; k < procedureArguments.size(); ++k) {
13375                                        Argument argumentModel = (Argument) procedureArguments.get(k);
13376                                        argument argumentElement = new argument();
13377                                        argumentElement.setId(String.valueOf(argumentModel.getId()));
13378                                        argumentElement.setName(argumentModel.getName());
13379                                        if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
13380                                                argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
13381                                                                + convertCoordinate(argumentModel.getEndPosition()));
13382                                        }
13383
13384                                        argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
13385                                        argumentElement.setInout(argumentModel.getMode().name());
13386                                        procedure.getArguments().add(argumentElement);
13387                                }
13388                        }
13389                }
13390        }
13391
13392        private void appendProcedures(dataflow dataflow) {
13393                List<Procedure> procedures = this.modelManager.getProcedureModels();
13394
13395                for (int i = 0; i < procedures.size(); ++i) {
13396                        Procedure model = procedures.get(i);
13397                        if (model.getParentPackage() != null) {
13398                                continue;
13399                        }
13400                        procedure procedure = new procedure();
13401                        procedure.setId(String.valueOf(model.getId()));
13402                        if (!SQLUtil.isEmpty(model.getDatabase())) {
13403                                procedure.setDatabase(model.getDatabase());
13404                        }
13405                        if (!SQLUtil.isEmpty(model.getSchema())) {
13406                                procedure.setSchema(model.getSchema());
13407                        }
13408                        procedure.setServer(model.getServer());
13409                        procedure.setName(model.getName());
13410                        if (model.getType() != null) {
13411                                procedure.setType(model.getType().name().replace("sst", ""));
13412                        }
13413                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
13414                                procedure.setCoordinate(
13415                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
13416                        }
13417
13418                        dataflow.getProcedures().add(procedure);
13419
13420                        List<Argument> arguments = model.getArguments();
13421
13422                        for (int j = 0; j < arguments.size(); ++j) {
13423                                Argument argumentModel = (Argument) arguments.get(j);
13424                                argument argumentElement = new argument();
13425                                argumentElement.setId(String.valueOf(argumentModel.getId()));
13426                                argumentElement.setName(argumentModel.getName());
13427                                if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
13428                                        argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
13429                                                        + convertCoordinate(argumentModel.getEndPosition()));
13430                                }
13431
13432                                argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
13433                                argumentElement.setInout(argumentModel.getMode().name());
13434                                procedure.getArguments().add(argumentElement);
13435                        }
13436                }
13437        }
13438
13439        private void appendProcesses(dataflow dataflow) {
13440                List<Process> processes = this.modelManager.getProcessModels();
13441
13442                for (int i = 0; i < processes.size(); ++i) {
13443                        Process model = processes.get(i);
13444                        process process = new process();
13445                        process.setId(String.valueOf(model.getId()));
13446                        if (!SQLUtil.isEmpty(model.getDatabase())) {
13447                                process.setDatabase(model.getDatabase());
13448                        }
13449                        if (!SQLUtil.isEmpty(model.getSchema())) {
13450                                process.setSchema(model.getSchema());
13451                        }
13452                        process.setServer(model.getServer());
13453                        process.setName(getProcessName(model));
13454                        if (!SQLUtil.isEmpty(model.getProcedureName())) {
13455                                process.setProcedureName(model.getProcedureName());
13456                        }
13457                        if (model.getProcedureId() != null) {
13458                                process.setProcedureId(String.valueOf(model.getProcedureId()));
13459                        }
13460                        if (!SQLUtil.isEmpty(model.getQueryHashId())) {
13461                                process.setQueryHashId(model.getQueryHashId());
13462                        }
13463                        if (model.getGspObject() != null) {
13464                                process.setType(model.getGspObject().sqlstatementtype.name());
13465                        }
13466                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
13467                                process.setCoordinate(
13468                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
13469                        }
13470                        if (model.getTransforms() != null && !model.getTransforms().isEmpty()) {
13471                                for (Transform transformItem : model.getTransforms()) {
13472                                        process.addTransform(transformItem);
13473                                }
13474                        }
13475                        dataflow.getProcesses().add(process);
13476                }
13477        }
13478
13479        private void appendTables(dataflow dataflow) {
13480                List<TTable> tables = modelManager.getBaseTables();
13481                Map<String, table> tableMap = new HashMap<String, table>();
13482                Set<Long> tableModelIds = new HashSet<Long>();
13483                for (int i = 0; i < tables.size(); i++) {
13484                        Object model = modelManager.getModel(tables.get(i));
13485                        if (model instanceof Table) {
13486                                Table tableModel = (Table) model;
13487                                if(tableModelIds.contains(tableModel.getId())) {
13488                                        continue;
13489                                }
13490                                else {
13491                                        tableModelIds.add(tableModel.getId());
13492                                }
13493                                if (tableModel.isView()) {
13494                                        continue;
13495                                }
13496                                if (tableModel.isStage()) {
13497                                        appendStageModel(dataflow, tableModel);
13498                                        continue;
13499                                }
13500                                if (tableModel.isSequence()) {
13501                                        appendSequenceModel(dataflow, tableModel);
13502                                        continue;
13503                                }
13504                                if (tableModel.isDataSource()) {
13505                                        appendDataSourceModel(dataflow, tableModel);
13506                                        continue;
13507                                }
13508                                if (tableModel.isDatabase()) {
13509                                        appendDatabaseModel(dataflow, tableModel);
13510                                        continue;
13511                                }
13512                                if (tableModel.isSchema()) {
13513                                        appendSchemaModel(dataflow, tableModel);
13514                                        continue;
13515                                }
13516                                if (tableModel.isStream()) {
13517                                        appendStreamModel(dataflow, tableModel);
13518                                        continue;
13519                                }
13520                                if (tableModel.isPath()) {
13521                                        appendPathModel(dataflow, tableModel);
13522                                        continue;
13523                                }
13524                                if (tableModel.isVariable() && !tableModel.isCursor()) {
13525                                        appendVariableModel(dataflow, tableModel);
13526                                        continue;
13527                                }
13528                                if (tableModel.isCursor()) {
13529                                        appendCursorModel(dataflow, tableModel);
13530                                        continue;
13531                                }
13532                                if (tableModel.isConstant()) {
13533                                        appendConstantModel(dataflow, tableModel);
13534                                        continue;
13535                                }
13536                                if (!tableIds.contains(tableModel.getId())) {
13537                                        appendTableModel(dataflow, tableModel, tableMap);
13538                                        tableIds.add(tableModel.getId());
13539                                }
13540                        } else if (model instanceof QueryTable) {
13541                                QueryTable queryTable = (QueryTable) model;
13542                                if (!tableIds.contains(queryTable.getId())) {
13543                                        appendResultSet(dataflow, queryTable);
13544                                        tableIds.add(queryTable.getId());
13545                                }
13546                        }
13547                }
13548
13549                List<Table> tableNames = modelManager.getTablesByName();
13550                tableNames.addAll(modelManager.getDropTables());
13551                
13552                for (int i = 0; i < tableNames.size(); i++) {
13553                        Table tableModel = tableNames.get(i);
13554                        if(tableModelIds.contains(tableModel.getId())) {
13555                                continue;
13556                        }
13557                        else {
13558                                tableModelIds.add(tableModel.getId());
13559                        }
13560                        if (tableModel.isView()) {
13561                                continue;
13562                        }
13563                        if (tableModel.isDatabase()) {
13564                                appendDatabaseModel(dataflow, tableModel);
13565                                continue;
13566                        }
13567                        if (tableModel.isSchema()) {
13568                                appendSchemaModel(dataflow, tableModel);
13569                                continue;
13570                        }
13571                        if (tableModel.isStage()) {
13572                                appendStageModel(dataflow, tableModel);
13573                                continue;
13574                        }
13575                        if (tableModel.isSequence()) {
13576                                appendSequenceModel(dataflow, tableModel);
13577                                continue;
13578                        }
13579                        if (tableModel.isDataSource()) {
13580                                appendDataSourceModel(dataflow, tableModel);
13581                                continue;
13582                        }
13583                        if (tableModel.isStream()) {
13584                                appendStreamModel(dataflow, tableModel);
13585                                continue;
13586                        }
13587                        if (tableModel.isPath()) {
13588                                appendPathModel(dataflow, tableModel);
13589                                continue;
13590                        }
13591                        if (tableModel.isVariable()) {
13592                                appendVariableModel(dataflow, tableModel);
13593                                continue;
13594                        }
13595                        if (tableModel.isCursor()) {
13596                                appendCursorModel(dataflow, tableModel);
13597                                continue;
13598                        }
13599                        if (tableModel.isConstant()) {
13600                                appendConstantModel(dataflow, tableModel);
13601                                continue;
13602                        }
13603                        if (!tableIds.contains(tableModel.getId())) {
13604                                appendTableModel(dataflow, tableModel, tableMap);
13605                                tableIds.add(tableModel.getId());
13606                        }
13607                }
13608        }
13609
13610        private void appendConstantModel(dataflow dataflow, Table tableModel) {
13611                table constantElement = new table();
13612                constantElement.setId(String.valueOf(tableModel.getId()));
13613                if (!SQLUtil.isEmpty(tableModel.getDatabase())) {
13614                        constantElement.setDatabase(tableModel.getDatabase());
13615                }
13616                if (!SQLUtil.isEmpty(tableModel.getSchema())) {
13617                        constantElement.setSchema(tableModel.getSchema());
13618                }
13619                constantElement.setServer(tableModel.getServer());
13620                constantElement.setName(getConstantName(tableModel));
13621                constantElement.setType("constantTable");
13622
13623                if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) {
13624                        constantElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + ","
13625                                        + convertCoordinate(tableModel.getEndPosition()));
13626                }
13627                dataflow.getTables().add(constantElement);
13628
13629                List<TableColumn> columns = tableModel.getColumns();
13630                for (int j = 0; j < columns.size(); j++) {
13631                        TableColumn columnModel = (TableColumn) columns.get(j);
13632                        column columnElement = new column();
13633                        columnElement.setId(String.valueOf(columnModel.getId()));
13634                        columnElement.setName(columnModel.getName());
13635                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13636                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13637                                                + convertCoordinate(columnModel.getEndPosition()));
13638                        }
13639                        constantElement.getColumns().add(columnElement);
13640                }
13641        }
13642
13643        private void appendTableModel(dataflow dataflow, Table tableModel, Map<String, table> tableMap) {
13644                if(tableModel.getSubType() == SubType.unnest) {}
13645                table tableElement = new table();
13646                tableElement.setId(String.valueOf(tableModel.getId()));
13647                if (!SQLUtil.isEmpty(tableModel.getDatabase())) {
13648                        tableElement.setDatabase(tableModel.getDatabase());
13649                }
13650                if (!SQLUtil.isEmpty(tableModel.getSchema())) {
13651                        tableElement.setSchema(tableModel.getSchema());
13652                }
13653                tableElement.setServer(tableModel.getServer());
13654                tableElement.setName(tableModel.getName());
13655                tableElement.setDisplayName(tableModel.getDisplayName());
13656                tableElement.setStarStmt(tableModel.getStarStmt());
13657                if(tableModel.isFromDDL()) {
13658                        tableElement.setFromDDL(String.valueOf(tableModel.isFromDDL()));
13659                }
13660
13661                if (tableModel.isPseudo()) {
13662                        tableElement.setType("pseudoTable");
13663                } else {
13664                        tableElement.setType("table");
13665                }
13666
13667                if (tableModel.getSubType() != null) {
13668                        if (tableModel.getSubType() == SubType.unnest) {
13669                                tableElement.setType(SubType.unnest.name());
13670                        }
13671                        else {
13672                                tableElement.setSubType(tableModel.getSubType().name());
13673                        }
13674                }
13675                if (tableModel.getParent() != null) {
13676                        tableElement.setParent(tableModel.getParent());
13677                }
13678                if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) {
13679                        tableElement.setAlias(tableModel.getAlias());
13680                }
13681                if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) {
13682                        tableElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + ","
13683                                        + convertCoordinate(tableModel.getEndPosition()));
13684                }
13685                if (tableModel.getProcesses() != null) {
13686                        List<String> processIds = new ArrayList<String>();
13687                        for (Process process : tableModel.getProcesses()) {
13688                                processIds.add(String.valueOf(process.getId()));
13689                        }
13690                        tableElement.setProcessIds(processIds);
13691                }
13692
13693                table oldTableElement = null;
13694                String tableFullName = DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getQualifiedTableName(tableElement));
13695                
13696                if(tableMap.containsKey(tableFullName)) {
13697                        oldTableElement = tableMap.get(tableFullName);
13698                }
13699                else {
13700                        tableMap.put(tableFullName, tableElement);
13701                }
13702                
13703                if (tableModel.getSubType() == SubType.unnest) {
13704                        dataflow.getResultsets().add(tableElement);
13705                } else {
13706                        dataflow.getTables().add(tableElement);
13707                }
13708
13709                List<TableColumn> columns = tableModel.getColumns();
13710
13711                if (containStarColumn(columns)) {
13712                        for (TableColumn column : columns) {
13713                                if (column.getName().endsWith("*")) {
13714                                        for (TableColumn starElement : columns) {
13715                                                if (starElement == column) {
13716                                                        continue;
13717                                                }
13718                                                if (starElement.isNotBindStarLinkColumn()) {
13719                                                        continue;
13720                                                }
13721                                                TObjectName columnObject = starElement.getColumnObject();
13722                                                column.bindStarLinkColumn(columnObject);
13723                                        }
13724                                        if (tableModel.isCreateTable() && column.isExpandStar()) {
13725                                                column.setShowStar(false);
13726                                        }
13727                                }
13728                        }
13729                }
13730
13731                for (int j = 0; j < columns.size(); j++) {
13732                        TableColumn columnModel = columns.get(j);
13733
13734                        if(oldTableElement != null){
13735                                if(!CollectionUtil.isEmpty(oldTableElement.getColumns())){
13736                                        for(column oldColumnElement: oldTableElement.getColumns()){
13737                                                if(oldColumnElement.getName().equalsIgnoreCase(columnModel.getName())){
13738                                                        if(columnModel.getDataType() == null && oldColumnElement.getDataType() != null){
13739                                                                columnModel.setDataType(oldColumnElement.getDataType());
13740                                                        }
13741                                                        if(columnModel.getPrimaryKey() == null && oldColumnElement.isPrimaryKey() != null){
13742                                                                columnModel.setPrimaryKey(oldColumnElement.isPrimaryKey());
13743                                                        }
13744                                                        if(columnModel.getIndexKey() == null && oldColumnElement.isIndexKey() != null){
13745                                                                columnModel.setIndexKey(oldColumnElement.isIndexKey());
13746                                                        }
13747                                                        if(columnModel.getUnqiueKey() == null && oldColumnElement.isUnqiueKey() != null){
13748                                                                columnModel.setUnqiueKey(oldColumnElement.isUnqiueKey());
13749                                                        }
13750                                                        if(columnModel.getForeignKey() == null && oldColumnElement.isForeignKey() != null){
13751                                                                columnModel.setForeignKey(oldColumnElement.isForeignKey());
13752                                                        }
13753
13754                                                        if(oldColumnElement.getDataType() == null && columnModel.getDataType() != null){
13755                                                                oldColumnElement.setDataType(columnModel.getDataType());
13756                                                        }
13757                                                        if(oldColumnElement.isPrimaryKey() == null && columnModel.getPrimaryKey() != null){
13758                                                                oldColumnElement.setPrimaryKey(columnModel.getPrimaryKey());
13759                                                        }
13760                                                        if(oldColumnElement.isIndexKey() == null && columnModel.getIndexKey() != null){
13761                                                                oldColumnElement.setIndexKey(columnModel.getIndexKey());
13762                                                        }
13763                                                        if(oldColumnElement.isUnqiueKey() == null && columnModel.getUnqiueKey() != null){
13764                                                                oldColumnElement.setUnqiueKey(columnModel.getUnqiueKey());
13765                                                        }
13766                                                        if(oldColumnElement.isForeignKey() == null && columnModel.getForeignKey() != null){
13767                                                                oldColumnElement.setForeignKey(columnModel.getForeignKey());
13768                                                        }
13769                                                        break;
13770                                                }
13771                                        }
13772                                }
13773
13774                        }
13775
13776                        if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn() && !columnModel.isVariant()) {
13777                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
13778                                for (int k = 0; k < starLinkColumnList.size(); k++) {
13779                                        column columnElement = new column();
13780                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
13781                                        String columnName = starLinkColumnList.get(k);
13782                                        if (containStarColumn(columns, columnName)) {
13783                                                continue;
13784                                        }
13785                                        columnElement.setName(columnName);
13786                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13787                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13788                                                                + convertCoordinate(columnModel.getEndPosition()));
13789                                        }
13790                                        if (columnModel.getForeignKey()) {
13791                                                columnElement.setForeignKey(columnModel.getForeignKey());
13792                                        }
13793                                        if (columnModel.getIndexKey()) {
13794                                                columnElement.setIndexKey(columnModel.getIndexKey());
13795                                        }
13796                                        if (columnModel.getPrimaryKey()) {
13797                                                columnElement.setPrimaryKey(columnModel.getPrimaryKey());
13798                                        }
13799                                        if (columnModel.getUnqiueKey()) {
13800                                                columnElement.setUnqiueKey(columnModel.getUnqiueKey());
13801                                        }
13802                                        if (columnModel.getDataType() != null) {
13803                                                columnElement.setDataType(columnModel.getDataType());
13804                                        }
13805                                        tableElement.getColumns().add(columnElement);
13806                                }
13807                                if (columnModel.isShowStar()) {
13808                                        column columnElement = new column();
13809                                        columnElement.setId(String.valueOf(columnModel.getId()));
13810                                        columnElement.setName(columnModel.getName());
13811                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13812                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13813                                                                + convertCoordinate(columnModel.getEndPosition()));
13814                                        }
13815                                        if (columnModel.getForeignKey()) {
13816                                                columnElement.setForeignKey(columnModel.getForeignKey());
13817                                        }
13818                                        if (columnModel.getIndexKey()) {
13819                                                columnElement.setIndexKey(columnModel.getIndexKey());
13820                                        }
13821                                        if (columnModel.getPrimaryKey()) {
13822                                                columnElement.setPrimaryKey(columnModel.getPrimaryKey());
13823                                        }
13824                                        if (columnModel.getUnqiueKey()) {
13825                                                columnElement.setUnqiueKey(columnModel.getUnqiueKey());
13826                                        }
13827                                        if (columnModel.getDataType() != null) {
13828                                                columnElement.setDataType(columnModel.getDataType());
13829                                        }
13830                                        tableElement.getColumns().add(columnElement);
13831                                }
13832                        } else {
13833                                column columnElement = new column();
13834                                columnElement.setId(String.valueOf(columnModel.getId()));
13835                                columnElement.setName(columnModel.getName());
13836                                columnElement.setDisplayName(columnModel.getDisplayName());
13837                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13838                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13839                                                        + convertCoordinate(columnModel.getEndPosition()));
13840                                }
13841                                if (columnModel.isPseduo()) {
13842                                        columnElement.setSource("system");
13843                                }
13844                                if (columnModel.getForeignKey()) {
13845                                        columnElement.setForeignKey(columnModel.getForeignKey());
13846                                }
13847                                if (columnModel.getIndexKey()) {
13848                                        columnElement.setIndexKey(columnModel.getIndexKey());
13849                                }
13850                                if (columnModel.getPrimaryKey()) {
13851                                        columnElement.setPrimaryKey(columnModel.getPrimaryKey());
13852                                }
13853                                if (columnModel.getUnqiueKey()) {
13854                                        columnElement.setUnqiueKey(columnModel.getUnqiueKey());
13855                                }
13856                                if (columnModel.getDataType() != null) {
13857                                        columnElement.setDataType(columnModel.getDataType());
13858                                }
13859                                tableElement.getColumns().add(columnElement);
13860                        }
13861                }
13862
13863                TableRelationRows relationRows = tableModel.getRelationRows();
13864                if (relationRows.hasRelation()) {
13865                        column relationRowsElement = new column();
13866                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13867                        relationRowsElement.setName(relationRows.getName());
13868                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13869                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13870                                                + convertCoordinate(relationRows.getEndPosition()));
13871                        }
13872                        relationRowsElement.setSource("system");
13873                        tableElement.getColumns().add(relationRowsElement);
13874                }
13875        }
13876
13877        private boolean containStarColumn(List<TableColumn> columns, String qualifiedColumnName) {
13878                for (TableColumn tableColumn : columns) {
13879                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) {
13880                                return true;
13881                        }
13882                }
13883                return false;
13884        }
13885
13886        private TableColumn searchTableColumn(List<TableColumn> columns, String qualifiedColumnName) {
13887                for (TableColumn tableColumn : columns) {
13888                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) {
13889                                return tableColumn;
13890                        }
13891                }
13892                return null;
13893        }
13894
13895        private boolean containStarColumn(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) {
13896                for (RelationshipElement element : elements) {
13897                        if (element.getElement() instanceof TableColumn) {
13898                                if (DlineageUtil.getIdentifierNormalColumnName(((TableColumn) element.getElement()).getName())
13899                                                .equals(qualifiedColumnName)) {
13900                                        return true;
13901                                }
13902                        } else if (element.getElement() instanceof ResultColumn) {
13903                                if (DlineageUtil.getIdentifierNormalColumnName(((ResultColumn) element.getElement()).getName())
13904                                                .equals(qualifiedColumnName)) {
13905                                        return true;
13906                                }
13907                        }
13908                }
13909                return false;
13910        }
13911
13912        private void analyzeSelectStmt(TSelectSqlStatement stmt) {
13913                if (!accessedSubqueries.contains(stmt)) {
13914                        accessedSubqueries.add(stmt);
13915                } else {
13916                        if (modelManager.getModel(stmt) != null) {
13917                                return;
13918                        }
13919                }
13920
13921                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
13922
13923                        if (!accessedStatements.contains(stmt.getLeftStmt())) {
13924                                accessedStatements.add(stmt.getLeftStmt());
13925                                analyzeSelectStmt(stmt.getLeftStmt());
13926                        }
13927
13928                        if (!accessedStatements.contains(stmt.getRightStmt())) {
13929                                accessedStatements.add(stmt.getRightStmt());
13930                                analyzeSelectStmt(stmt.getRightStmt());
13931                        }
13932
13933                        stmtStack.push(stmt);
13934                        SelectSetResultSet resultSet = modelFactory.createSelectSetResultSet(stmt);
13935
13936                        ResultSet leftResultSetModel = (ResultSet) modelManager.getModel(stmt.getLeftStmt());
13937                        if (leftResultSetModel != null && leftResultSetModel != resultSet
13938                                        && !leftResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
13939                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
13940                                impactRelation.setEffectType(EffectType.select);
13941                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
13942                                                leftResultSetModel.getRelationRows()));
13943                                impactRelation.setTarget(
13944                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
13945                        }
13946                        
13947                        ResultSet rightResultSetModel = (ResultSet) modelManager.getModel(stmt.getRightStmt());
13948                        if (rightResultSetModel != null && rightResultSetModel != resultSet
13949                                        && !rightResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
13950                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
13951                                impactRelation.setEffectType(EffectType.select);
13952                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
13953                                                rightResultSetModel.getRelationRows()));
13954                                impactRelation.setTarget(
13955                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
13956                        }
13957                        
13958                        if ((leftResultSetModel != null && leftResultSetModel.isDetermined())
13959                                        || (rightResultSetModel != null && rightResultSetModel.isDetermined())) {
13960                                resultSet.setDetermined(true);
13961                        }
13962                        
13963                        if (resultSet.getColumns() == null || resultSet.getColumns().isEmpty()) {
13964                                if (getResultColumnList(stmt.getLeftStmt()) != null) {
13965                                        createSelectSetResultColumns(resultSet, stmt.getLeftStmt());
13966                                } else if (getResultColumnList(stmt.getRightStmt()) != null) {
13967                                        createSelectSetResultColumns(resultSet, stmt.getRightStmt());
13968                                }
13969                        }
13970
13971                        List<ResultColumn> columns = resultSet.getColumns();
13972                        for (int i = 0; i < columns.size(); i++) {
13973                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
13974                                relation.setEffectType(EffectType.select);
13975                                relation.setTarget(new ResultColumnRelationshipElement(columns.get(i)));
13976
13977                                if (!stmt.getLeftStmt().isCombinedQuery()) {
13978                                        ResultSet sourceResultSet = (ResultSet) modelManager
13979                                                        .getModel(stmt.getLeftStmt().getResultColumnList());
13980                                        if (sourceResultSet!=null && sourceResultSet.getColumns().size() > i) {
13981                                                if (columns.get(i).getName().endsWith("*")) {
13982                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
13983                                                                relation.addSource(new ResultColumnRelationshipElement(column));
13984                                                        }
13985                                                } else {
13986                                                        relation.addSource(
13987                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
13988                                                }
13989                                        }
13990                                } else {
13991                                        ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getLeftStmt());
13992                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
13993                                                if (columns.get(i).getName().endsWith("*")) {
13994                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
13995                                                                relation.addSource(new ResultColumnRelationshipElement(column));
13996                                                        }
13997                                                } else {
13998                                                        relation.addSource(
13999                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
14000                                                }
14001                                        }
14002                                }
14003
14004                                if (!stmt.getRightStmt().isCombinedQuery()) {
14005                                        ResultSet sourceResultSet = (ResultSet) modelManager
14006                                                        .getModel(stmt.getRightStmt().getResultColumnList());
14007                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
14008                                                if (columns.get(i).getName().endsWith("*")) {
14009                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
14010                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14011                                                        }
14012                                                } else {
14013                                                        relation.addSource(
14014                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
14015                                                }
14016                                        } else if (sourceResultSet != null) {
14017                                                for (ResultColumn column : sourceResultSet.getColumns()) {
14018                                                        if (column.hasStarLinkColumn()) {
14019                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14020                                                        }
14021                                                }
14022                                        }
14023                                } else {
14024                                        ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getRightStmt());
14025                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
14026                                                relation.addSource(new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
14027                                        } else if (sourceResultSet != null) {
14028                                                for (ResultColumn column : sourceResultSet.getColumns()) {
14029                                                        if (column.hasStarLinkColumn()) {
14030                                                                relation.addSource(new ResultColumnRelationshipElement(column));
14031                                                        }
14032                                                }
14033                                        }
14034                                }
14035                        }
14036                        
14037                        analyzeSelectIntoClause(stmt);
14038                        
14039                        stmtStack.pop();
14040                } else {
14041
14042                        // handle hive stmt, issue_id I3SGZB
14043                        if (stmt.getHiveBodyList() != null && stmt.getHiveBodyList().size() > 0) {
14044                                stmtStack.push(stmt);
14045                                hiveFromTables = stmt.tables;
14046                                if (hiveFromTables != null) {
14047                                        for (int i = 0; i < hiveFromTables.size(); i++) {
14048                                                modelFactory.createTable(hiveFromTables.getTable(i));
14049                                        }
14050                                }
14051                                for (int i = 0; i < stmt.getHiveBodyList().size(); i++) {
14052                                        analyzeCustomSqlStmt(stmt.getHiveBodyList().get(i));
14053                                }
14054                                stmtStack.pop();
14055                                return;
14056                        }
14057                        
14058                        if (stmt.getTransformClause() != null) {
14059                                analyzeHiveTransformClause(stmt, stmt.getTransformClause());
14060                                return;
14061                        }
14062
14063                        if (stmt.getResultColumnList() == null) {
14064                                return;
14065                        }
14066
14067                        stmtStack.push(stmt);
14068
14069                        TTableList fromTables = stmt.tables;
14070                        if ((fromTables == null || fromTables.size() == 0)
14071                                        && (hiveFromTables != null && hiveFromTables.size() > 0)) {
14072                                fromTables = hiveFromTables;
14073                        }
14074
14075                        for (int i = 0; i < fromTables.size(); i++) {
14076                                TTable table = fromTables.getTable(i);
14077                                if (table.getLateralViewList() != null && !table.getLateralViewList().isEmpty()) {
14078                                        analyzeTableSubquery(table);
14079                                        analyzeLateralView(stmt, table, table.getLateralViewList());
14080                                        stmtStack.pop();
14081                                        return;
14082                                }
14083                                if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvpresto) {
14084                                        analyzeTableSubquery(table);
14085                                        analyzePrestoUnnest(stmt, table);
14086                                        stmtStack.pop();
14087                                        return;
14088                                }
14089                                if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvbigquery) {
14090                                        analyzeBigQueryUnnest(stmt, table);
14091                                }
14092                        }
14093                        
14094                        //用来获取 pivotedTable 对应的columns
14095                        TPivotedTable pivotedTable = null; 
14096                        if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
14097                                for (TJoin join : stmt.getJoins()) {
14098                                        if (join.getTable() != null && join.getTable().getPivotedTable() != null) {
14099                                                if (isUnPivotedTable(join.getTable().getPivotedTable())) {
14100                                                        analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable());
14101                                                        pivotedTable = join.getTable().getPivotedTable();
14102                                                } else {
14103                                                        analyzePivotedTable(stmt, join.getTable().getPivotedTable());
14104                                                        pivotedTable = join.getTable().getPivotedTable();
14105                                                }
14106                                        }
14107                                }
14108                        }
14109
14110                        for (int i = 0; i < fromTables.size(); i++) {
14111                                TTable table = fromTables.getTable(i);
14112
14113                                if (table.getFuncCall() != null) {
14114                                        TFunctionCall functionCall = table.getFuncCall();
14115                                        Procedure callee = modelManager.getProcedureByName(
14116                                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
14117                                        if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
14118                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
14119                                                callee = modelManager.getProcedureByName(
14120                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
14121                                        }
14122
14123                                        if(callee!=null) {
14124                                                if (callee.getArguments() != null) {
14125                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
14126                                                                Argument argument = callee.getArguments().get(j);
14127                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
14128                                                                if(variable!=null) {
14129                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
14130                                                                                Transform transform = new Transform();
14131                                                                                transform.setType(Transform.FUNCTION);
14132                                                                                transform.setCode(functionCall);
14133                                                                                variable.getColumns().get(0).setTransform(transform);
14134                                                                        }
14135                                                                        Process process = modelFactory.createProcess(functionCall);
14136                                                                        variable.addProcess(process);
14137                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
14138                                                                }
14139                                                        }
14140                                                }
14141                                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
14142                                                                .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
14143                                                if (functionTableModelObjs != null) {
14144                                                        modelManager.bindModel(table, functionTableModelObjs.iterator().next());
14145                                                }
14146                                                continue;
14147                                        } else {
14148                                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
14149                                                                .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
14150                                                if (functionTableModelObjs == null) {
14151//                                                      Procedure procedure = modelManager.getProcedureByName(DlineageUtil
14152//                                                                      .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
14153//                                                      if (procedure != null) {
14154                                                                createFunction(table.getFuncCall());
14155                                                                continue;
14156//                                                      }
14157                                                }
14158                                                if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof Table) {
14159                                                        Table functionTableModel = (Table) functionTableModelObjs.iterator().next();
14160                                                        if (functionTableModel.getColumns() != null) {
14161                                                                Table functionTable = modelFactory.createTableFromCreateDDL(table, true);
14162                                                                if (functionTable == functionTableModel)
14163                                                                        continue;
14164                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
14165                                                                        TableColumn column = modelFactory.createTableColumn(functionTable,
14166                                                                                        functionTableModel.getColumns().get(j).getColumnObject(), true);
14167                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14168                                                                        relation.setEffectType(EffectType.select);
14169                                                                        relation.setTarget(new TableColumnRelationshipElement(column));
14170                                                                        relation.addSource(
14171                                                                                        new TableColumnRelationshipElement(functionTableModel.getColumns().get(j)));
14172                                                                }
14173                                                        }
14174                                                } else if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) {
14175                                                        ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next();
14176                                                        if (functionTableModel.getColumns() != null) {
14177                                                                Table functionTable = modelFactory.createTableFromCreateDDL(table, true);
14178                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
14179                                                                        TParseTreeNode columnObj = functionTableModel.getColumns().get(j).getColumnObject();
14180                                                                        if (columnObj instanceof TObjectName) {
14181                                                                                TableColumn column = modelFactory.createTableColumn(functionTable,
14182                                                                                                (TObjectName) columnObj, true);
14183                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14184                                                                                relation.setEffectType(EffectType.select);
14185                                                                                relation.setTarget(new TableColumnRelationshipElement(column));
14186                                                                                relation.addSource(new ResultColumnRelationshipElement(
14187                                                                                                functionTableModel.getColumns().get(j)));
14188                                                                        } else if (columnObj instanceof TResultColumn) {
14189                                                                                TableColumn column = modelFactory.createTableColumn(functionTable,
14190                                                                                                (TResultColumn) columnObj);
14191                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14192                                                                                relation.setEffectType(EffectType.select);
14193                                                                                relation.setTarget(new TableColumnRelationshipElement(column));
14194                                                                                relation.addSource(new ResultColumnRelationshipElement(
14195                                                                                                functionTableModel.getColumns().get(j)));
14196                                                                        }
14197                                                                }
14198                                                        }
14199                                                }
14200                                        }
14201                                }
14202                                
14203                                if (table.getPartitionExtensionClause() != null
14204                                                && table.getPartitionExtensionClause().getKeyValues() != null) {
14205                                        TExpressionList values = table.getPartitionExtensionClause().getKeyValues();
14206                                        Table tableModel = modelFactory.createTable(table);
14207                                        for (TExpression value : values) {
14208                                                if (value.getExpressionType() == EExpressionType.simple_constant_t) {
14209                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14210                                                        impactRelation.setEffectType(EffectType.select);
14211                                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
14212                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, value.getConstantOperand());
14213                                                        impactRelation.addSource(new TableColumnRelationshipElement(constantColumn));
14214                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
14215                                                                        tableModel.getRelationRows()));
14216                                                }
14217                                        }
14218                                }
14219
14220                                if (table.getSubquery() != null) {
14221                                        QueryTable queryTable = modelFactory.createQueryTable(table);
14222                                        TSelectSqlStatement subquery = table.getSubquery();
14223                                        analyzeSelectStmt(subquery);
14224
14225                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
14226                                        if (resultSetModel != null && resultSetModel.isDetermined()) {
14227                                                queryTable.setDetermined(true);
14228                                        }
14229
14230                                        if (resultSetModel != null && resultSetModel != queryTable
14231                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
14232                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14233                                                impactRelation.setEffectType(EffectType.select);
14234                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14235                                                                resultSetModel.getRelationRows()));
14236                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14237                                                                queryTable.getRelationRows()));
14238                                        }
14239
14240                                        if (resultSetModel != null && resultSetModel != queryTable
14241                                                        && queryTable.getTableObject().getAliasClause() != null
14242                                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
14243                                                for (int j = 0; j < queryTable.getColumns().size()
14244                                                                && j < resultSetModel.getColumns().size(); j++) {
14245                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
14246                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
14247
14248                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
14249                                                        queryRalation.setEffectType(EffectType.select);
14250                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14251                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14252                                                }
14253                                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
14254                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
14255                                                                .getModel(subquery);
14256                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
14257                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
14258                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
14259                                                                        sourceColumn);
14260                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
14261                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
14262                                                        }
14263                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
14264                                                        selectSetRalation.setEffectType(EffectType.select);
14265                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14266                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14267                                                }
14268                                        }
14269                                } else if (table.getOutputMerge() != null) {
14270                                        QueryTable queryTable = modelFactory.createQueryTable(table);
14271                                        TMergeSqlStatement subquery = table.getOutputMerge();
14272                                        analyzeMergeStmt(subquery);
14273
14274                                        for (TResultColumn column : subquery.getOutputClause().getSelectItemList()) {
14275                                                modelFactory.createResultColumn(queryTable, column);
14276                                                analyzeResultColumn(column, EffectType.select);
14277                                        }
14278
14279                                        ResultSet resultSetModel = (ResultSet) modelManager
14280                                                        .getModel(subquery.getOutputClause().getSelectItemList());
14281
14282                                        if (resultSetModel != null && resultSetModel != queryTable
14283                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
14284                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14285                                                impactRelation.setEffectType(EffectType.select);
14286                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14287                                                                resultSetModel.getRelationRows()));
14288                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14289                                                                queryTable.getRelationRows()));
14290                                        }
14291
14292                                        if (resultSetModel != null && resultSetModel != queryTable
14293                                                        && queryTable.getTableObject().getAliasClause() != null
14294                                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
14295                                                for (int j = 0; j < queryTable.getColumns().size()
14296                                                                && j < resultSetModel.getColumns().size(); j++) {
14297                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
14298                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
14299
14300                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
14301                                                        queryRalation.setEffectType(EffectType.select);
14302                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14303                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14304                                                }
14305                                        }
14306                                } else if (table.getTableExpr() != null && table.getTableExpr().getSubQuery() != null) {
14307                                        QueryTable queryTable = modelFactory.createQueryTable(table);
14308                                        TSelectSqlStatement subquery = table.getTableExpr().getSubQuery();
14309                                        analyzeSelectStmt(subquery);
14310
14311                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
14312
14313                                        if (resultSetModel != null && resultSetModel != queryTable
14314                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
14315                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14316                                                impactRelation.setEffectType(EffectType.select);
14317                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14318                                                                resultSetModel.getRelationRows()));
14319                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14320                                                                queryTable.getRelationRows()));
14321                                        }
14322
14323                                        if (resultSetModel != null && resultSetModel != queryTable
14324                                                        && queryTable.getTableObject().getAliasClause() != null) {
14325                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
14326                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
14327                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
14328                                                                        sourceColumn);
14329
14330                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
14331                                                        queryRalation.setEffectType(EffectType.select);
14332                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14333                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14334                                                }
14335                                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
14336                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
14337                                                                .getModel(subquery);
14338                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
14339                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
14340                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
14341                                                                        sourceColumn);
14342                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
14343                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
14344                                                        }
14345                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
14346                                                        selectSetRalation.setEffectType(EffectType.select);
14347                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14348                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14349                                                }
14350                                        }
14351                                } else if (table.getCTE() != null) {
14352                                        QueryTable queryTable = modelFactory.createQueryTable(table);
14353
14354                                        TObjectNameList cteColumns = table.getCTE().getColumnList();
14355                                        if (cteColumns != null) {
14356                                                for (int j = 0; j < cteColumns.size(); j++) {
14357                                                        modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
14358                                                }
14359                                                queryTable.setDetermined(true);
14360                                        }
14361                                        TSelectSqlStatement subquery = table.getCTE().getSubquery();
14362                                        if (subquery != null && !stmtStack.contains(subquery) && subquery.getResultColumnList() != null) {
14363                                                analyzeSelectStmt(subquery);
14364
14365                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
14366                                                if (resultSetModel != null && resultSetModel != queryTable
14367                                                                && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
14368                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
14369                                                        impactRelation.setEffectType(EffectType.select);
14370                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14371                                                                        resultSetModel.getRelationRows()));
14372                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
14373                                                                        queryTable.getRelationRows()));
14374                                                }
14375
14376                                                if (subquery.getSetOperatorType() != ESetOperatorType.none) {
14377                                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
14378                                                                        .getModel(subquery);
14379                                                        int x = 0;
14380                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
14381                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
14382                                                                ResultColumn targetColumn = null;
14383                                                                if (cteColumns != null) {
14384                                                                        if (queryTable.getColumns().size() <= j) {
14385                                                                                for (int k = 0; k < queryTable.getColumns().size(); k++) {
14386                                                                                        if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName())
14387                                                                                                        || queryTable.getColumns().get(k).getName()
14388                                                                                                                        .equals(sourceColumn.getAlias())) {
14389                                                                                                targetColumn = queryTable.getColumns().get(k);
14390                                                                                        }
14391                                                                                }
14392                                                                        } else {
14393                                                                                if (x < j) {
14394                                                                                        x = j;
14395                                                                                }
14396                                                                                targetColumn = queryTable.getColumns().get(x);
14397                                                                                x++;
14398                                                                                if (resultSetModel.getColumns().get(j).getName().contains("*")
14399                                                                                                && x < cteColumns.size()) {
14400                                                                                        j--;
14401                                                                                }
14402                                                                        }
14403                                                                } else {
14404                                                                        targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
14405                                                                }
14406                                                                for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
14407                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
14408                                                                }
14409                                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
14410                                                                selectSetRalation.setEffectType(EffectType.select);
14411                                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14412                                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14413                                                        }
14414                                                        if (!queryTable.isDetermined()) {
14415                                                                queryTable.setDetermined(selectSetResultSetModel.isDetermined());
14416                                                        }
14417                                                } else {
14418                                                        int x = 0;
14419                                                        for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
14420                                                                ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
14421                                                                ResultColumn targetColumn = null;
14422                                                                if (cteColumns != null) {
14423                                                                        if (queryTable.getColumns().size() <= j) {
14424                                                                                for (int k = 0; k < queryTable.getColumns().size(); k++) {
14425                                                                                        if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName())
14426                                                                                                        || queryTable.getColumns().get(k).getName()
14427                                                                                                                        .equals(sourceColumn.getAlias())) {
14428                                                                                                targetColumn = queryTable.getColumns().get(k);
14429                                                                                        }
14430                                                                                }
14431                                                                        } else {
14432                                                                                if (x < j) {
14433                                                                                        x = j;
14434                                                                                }
14435                                                                                targetColumn = queryTable.getColumns().get(x);
14436                                                                                x++;
14437                                                                                if (resultSetModel.getColumns().get(j).getName().contains("*")
14438                                                                                                && x < cteColumns.size()) {
14439                                                                                        j--;
14440                                                                                }
14441                                                                        }
14442                                                                } else {
14443                                                                        targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
14444                                                                }
14445                                                                for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
14446                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
14447                                                                }
14448                                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
14449                                                                selectSetRalation.setEffectType(EffectType.select);
14450                                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
14451                                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
14452                                                        }
14453                                                        if (!queryTable.isDetermined()) {
14454                                                                queryTable.setDetermined(resultSetModel.isDetermined());
14455                                                        }
14456                                                }
14457                                        } else if (table.getCTE().getUpdateStmt() != null) {
14458                                                analyzeCustomSqlStmt(table.getCTE().getUpdateStmt());
14459                                        } else if (table.getCTE().getInsertStmt() != null) {
14460                                                analyzeCustomSqlStmt(table.getCTE().getInsertStmt());
14461                                        } else if (table.getCTE().getDeleteStmt() != null) {
14462                                                analyzeCustomSqlStmt(table.getCTE().getDeleteStmt());
14463                                        }
14464                                } else if (table.getTableType().name().startsWith("open")) {
14465                                        continue;
14466                                } else if (table.getTableType() == ETableSource.jsonTable) {
14467                                        Table functionTable = modelFactory.createJsonTable(table);
14468                                        TJsonTable jsonTable = table.getJsonTable();
14469                                        TColumnDefinitionList definitions = jsonTable.getColumnDefinitions();
14470                                        if (definitions != null) {
14471                                                for (int j = 0; j < definitions.size(); j++) {
14472                                                        TableColumn column = modelFactory.createTableColumn(functionTable,
14473                                                                        definitions.getColumn(j).getColumnName(), true);
14474                                                        if (definitions.getColumn(j).getColumnPath() != null) {
14475                                                                column.setDisplayName(
14476                                                                                column.getName() + ":" + definitions.getColumn(j).getColumnPath());
14477                                                        }
14478                                                }
14479                                        } else {
14480                                                TObjectName keyColumn = new TObjectName();
14481                                                keyColumn.setString("key");
14482                                                modelFactory.createJsonTableColumn(functionTable, keyColumn);
14483                                                TObjectName valueColumn = new TObjectName();
14484                                                valueColumn.setString("value");
14485                                                modelFactory.createJsonTableColumn(functionTable, valueColumn);
14486                                                TObjectName typeColumn = new TObjectName();
14487                                                typeColumn.setString("type");
14488                                                modelFactory.createJsonTableColumn(functionTable, typeColumn);
14489                                        }
14490
14491                                        functionTable.setCreateTable(true);
14492                                        functionTable.setSubType(SubType.function);
14493                                        modelManager.bindCreateModel(table, functionTable);
14494
14495                                        if (jsonTable.getJsonExpression() == null) {
14496                                                ErrorInfo errorInfo = new ErrorInfo();
14497                                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
14498                                                errorInfo.setErrorMessage("Can't handle the json table: " + jsonTable.toString());
14499                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(jsonTable.getStartToken().lineNo,
14500                                                                jsonTable.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
14501                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(jsonTable.getEndToken().lineNo,
14502                                                                jsonTable.getEndToken().columnNo + jsonTable.getEndToken().astext.length(),
14503                                                                ModelBindingManager.getGlobalHash()));
14504                                                errorInfo.fillInfo(this);
14505                                                errorInfos.add(errorInfo);
14506                                        } else {
14507                                                String jsonName = jsonTable.getJsonExpression().toString();
14508                                                if (!jsonName.startsWith("@")) {
14509                                                        columnsInExpr visitor = new columnsInExpr();
14510                                                        jsonTable.getJsonExpression().inOrderTraverse(visitor);
14511                                                        List<TObjectName> objectNames = visitor.getObjectNames();
14512                                                        List<TParseTreeNode> functions = visitor.getFunctions();
14513                                                        List<TParseTreeNode> constants = visitor.getConstants();
14514                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
14515
14516                                                        for (int j = 0; j < functionTable.getColumns().size(); j++) {
14517                                                                TableColumn tableColumn = functionTable.getColumns().get(j);
14518                                                                if (functions != null && !functions.isEmpty()) {
14519                                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
14520                                                                }
14521                                                                if (subquerys != null && !subquerys.isEmpty()) {
14522                                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
14523                                                                }
14524                                                                if (objectNames != null && !objectNames.isEmpty()) {
14525                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
14526                                                                }
14527                                                                if (constants != null && !constants.isEmpty()) {
14528                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
14529                                                                                        functions);
14530                                                                }
14531                                                        }
14532                                                } else {
14533                                                        TStatementList stmts = stmt.getGsqlparser().getSqlstatements();
14534                                                        for (int j = 0; j < stmts.size(); j++) {
14535                                                                TCustomSqlStatement item = stmts.get(j);
14536                                                                if (item instanceof TMssqlDeclare) {
14537                                                                        if (analyzeMssqlJsonDeclare((TMssqlDeclare) item, jsonName, functionTable)) {
14538                                                                                break;
14539                                                                        }
14540                                                                }
14541                                                        }
14542                                                }
14543                                        }
14544                                } else if (table.getLinkedColumns() != null && table.getLinkedColumns().size() > 0) {
14545                                        if (table.getTableType() == ETableSource.rowList && table.getRowList() != null
14546                                                        && table.getRowList().size() > 0) {
14547                                                Table tableModel = modelFactory.createTable(table);
14548                                                for (int j = 0; j < table.getRowList().size(); j++) {
14549                                                        TMultiTarget rowList = table.getRowList().getMultiTarget(j);
14550                                                        for (int k = 0; k < rowList.getColumnList().size(); k++) {
14551                                                                TResultColumn column = rowList.getColumnList().getResultColumn(k);
14552                                                                if (column.getFieldAttr() == null)
14553                                                                        continue;
14554                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel,
14555                                                                                column.getFieldAttr(), true);
14556
14557                                                                columnsInExpr visitor = new columnsInExpr();
14558                                                                column.getExpr().inOrderTraverse(visitor);
14559                                                                List<TObjectName> objectNames = visitor.getObjectNames();
14560                                                                List<TParseTreeNode> functions = visitor.getFunctions();
14561                                                                List<TParseTreeNode> constants = visitor.getConstants();
14562                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
14563
14564                                                                if (functions != null && !functions.isEmpty()) {
14565                                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
14566                                                                }
14567                                                                if (subquerys != null && !subquerys.isEmpty()) {
14568                                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
14569                                                                }
14570                                                                if (objectNames != null && !objectNames.isEmpty()) {
14571                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
14572                                                                }
14573                                                                if (constants != null && !constants.isEmpty()) {
14574                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
14575                                                                                        functions);
14576                                                                }
14577                                                        }
14578                                                }
14579                                        } else {
14580                                                if(table.getTableType() == ETableSource.pivoted_table) {
14581                                                        continue;
14582                                                }
14583                                                if (table.getTableType() == ETableSource.rowList) {
14584                                                        List<TResultColumnList> rowList = table.getValueClause().getRows();
14585                                                        
14586                                                        QueryTable tableModel = modelFactory.createQueryTable(table);
14587                                                        TAliasClause aliasClause = table.getAliasClause();
14588                                                        if (aliasClause != null && aliasClause.getColumns() != null) {
14589                                                                for (TObjectName column : aliasClause.getColumns()) {
14590                                                                        modelFactory.createResultColumn(tableModel, column, true);
14591                                                                }       
14592                                                        } else {        
14593                                                                int columnCount = rowList.get(0).size();
14594                                                                for (int j = 1; j <= columnCount; j++) {
14595                                                                        TObjectName columnName = new TObjectName();
14596                                                                        columnName.setString("column" + j);
14597                                                                        modelFactory.createResultColumn(tableModel, columnName, true);
14598                                                                }
14599                                                        }
14600                                                        tableModel.setDetermined(true);
14601                                                        
14602                                                        for (TResultColumnList resultColumnList : rowList) {
14603                                                                for (int j = 0; j < resultColumnList.size(); j++) {
14604                                                                        TResultColumn resultColumn = resultColumnList.getResultColumn(j);
14605                                                                        analyzeValueColumn(tableModel.getColumns().get(j), resultColumn, EffectType.select);
14606                                                                }
14607                                                        }
14608                                                        
14609                                                } else {
14610                                                        Table tableModel = modelFactory.createTable(table);
14611                                                        for (int j = 0; j < table.getLinkedColumns().size(); j++) {
14612                                                                TObjectName object = table.getLinkedColumns().getObjectName(j);
14613
14614                                                                if (object.getDbObjectType() == EDbObjectType.variable) {
14615                                                                        continue;
14616                                                                }
14617
14618                                                                if (object.getColumnNameOnly().startsWith("@")
14619                                                                                && (option.getVendor() == EDbVendor.dbvmssql
14620                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
14621                                                                        continue;
14622                                                                }
14623
14624                                                                if (object.getColumnNameOnly().startsWith(":")
14625                                                                                && (option.getVendor() == EDbVendor.dbvhana
14626                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
14627                                                                        continue;
14628                                                                }
14629
14630                                                                if (isBuiltInFunctionName(object) && isFromFunction(object)) {
14631                                                                        continue;
14632                                                                }
14633
14634                                                                if (!"*".equals(getColumnName(object))) {
14635                                                                        if (isStructColumn(object)) {
14636
14637                                                                        } else {
14638                                                                                if (pivotedTable != null) {
14639                                                                                        ResultColumn resultColumn = getPivotedTableColumn(pivotedTable, object);
14640                                                                                        if (resultColumn != null) {
14641                                                                                                continue;
14642                                                                                        }
14643                                                                                }
14644                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object,
14645                                                                                                false);
14646                                                                                if(tableColumn == null) {
14647                                                                                        continue;
14648                                                                                }
14649                                                                                if (table.getUnnestClause() != null
14650                                                                                                && table.getUnnestClause().getArrayExpr() != null) {
14651                                                                                        columnsInExpr visitor = new columnsInExpr();
14652                                                                                        table.getUnnestClause().getArrayExpr().inOrderTraverse(visitor);
14653
14654                                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
14655                                                                                        List<TParseTreeNode> functions = visitor.getFunctions();
14656
14657                                                                                        if (functions != null && !functions.isEmpty()) {
14658                                                                                                analyzeFunctionDataFlowRelation(tableColumn, functions,
14659                                                                                                                EffectType.select);
14660
14661                                                                                        }
14662
14663                                                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
14664                                                                                        if (subquerys != null && !subquerys.isEmpty()) {
14665                                                                                                analyzeSubqueryDataFlowRelation(tableColumn, subquerys,
14666                                                                                                                EffectType.select);
14667                                                                                        }
14668
14669                                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select,
14670                                                                                                        functions);
14671
14672                                                                                        List<TParseTreeNode> constants = visitor.getConstants();
14673                                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
14674                                                                                                        functions);
14675                                                                                }
14676                                                                        }
14677                                                                } else {
14678                                                                        boolean flag = false;
14679                                                                        for (TObjectName column : table.getLinkedColumns()) {
14680                                                                                if ("*".equals(getColumnName(column))) {
14681                                                                                        continue;
14682                                                                                }
14683                                                                                if (column.getLocation() != ESqlClause.where
14684                                                                                                && column.getLocation() != ESqlClause.joinCondition) {
14685                                                                                        flag = true;
14686                                                                                }
14687                                                                        }
14688                                                                        if (!flag) {
14689                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object,
14690                                                                                                false);
14691                                                                                if (tableColumn != null && !tableModel.hasSQLEnv()) {
14692                                                                                        tableColumn.setShowStar(true);
14693                                                                                }
14694                                                                        }
14695                                                                }
14696
14697                                                        }
14698                                                }
14699                                        }
14700                                }
14701                                else {
14702                                        modelFactory.createTable(table);
14703                                }
14704                        }
14705
14706                        if (pivotedTable!=null) {
14707                                for (TJoin join : stmt.getJoins()) {
14708                                        if (join.getTable() != null && join.getTable().getPivotedTable() != null) {
14709                                                if (isUnPivotedTable(join.getTable().getPivotedTable())) {
14710                                                        analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable());
14711                                                } else {
14712                                                        analyzePivotedTable(stmt, join.getTable().getPivotedTable());
14713                                                }
14714                                                stmtStack.pop();
14715                                                return;
14716                                        }
14717                                }
14718                        }
14719
14720                        if (!stmt.isCombinedQuery()) {
14721                                Object queryModel = modelManager.getModel(stmt.getResultColumnList());
14722
14723                                if (queryModel == null) {
14724                                        TSelectSqlStatement parentStmt = getParentSetSelectStmt(stmt);
14725                                        if (isTopResultSet(stmt) || parentStmt == null) {
14726                                                ResultSet resultSetModel = modelFactory.createResultSet(stmt,
14727                                                                isTopResultSet(stmt) && isShowTopSelectResultSet() && stmt.getIntoClause() == null);
14728
14729                                                createPseudoImpactRelation(stmt, resultSetModel, EffectType.select);
14730
14731                                                boolean isDetermined = true;
14732                                                Map<String, AtomicInteger> keyMap = new HashMap<String, AtomicInteger>();
14733                                                Set<String> columnNames = new HashSet<String>();
14734                                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
14735                                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
14736
14737                                                        if (column.getExpr().getComparisonType() == EComparisonType.equals
14738                                                                        && column.getExpr().getLeftOperand().getObjectOperand() != null) {
14739                                                                TObjectName columnObject = column.getExpr().getLeftOperand().getObjectOperand();
14740
14741                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
14742                                                                                columnObject);
14743                                                                if (columnObject.getDbObjectType() == EDbObjectType.variable) {
14744                                                                        Table variable = modelManager
14745                                                                                        .getTableByName(DlineageUtil.getTableFullName(columnObject.toString()));
14746                                                                        if (variable != null) {
14747                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14748                                                                                relation.setEffectType(EffectType.select);
14749                                                                                TableColumn columnModel = variable.getColumns().get(0);
14750                                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel));
14751                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
14752                                                                        } else {
14753                                                                                variable = modelFactory.createVariable(columnObject);
14754                                                                                variable.setCreateTable(true);
14755                                                                                variable.setSubType(SubType.record);
14756                                                                                TObjectName variableProperties = new TObjectName();
14757                                                                                variableProperties.setString("*");
14758                                                                                TableColumn variableProperty = modelFactory.createTableColumn(variable,
14759                                                                                                variableProperties, true);
14760                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
14761                                                                                relation.setEffectType(EffectType.select);
14762                                                                                relation.setTarget(new TableColumnRelationshipElement(variableProperty));
14763                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
14764                                                                        }
14765                                                                }
14766
14767                                                                columnsInExpr visitor = new columnsInExpr();
14768                                                                column.getExpr().getRightOperand().inOrderTraverse(visitor);
14769
14770                                                                List<TObjectName> objectNames = visitor.getObjectNames();
14771                                                                List<TParseTreeNode> functions = visitor.getFunctions();
14772
14773                                                                if (functions != null && !functions.isEmpty()) {
14774                                                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.select);
14775
14776                                                                }
14777
14778                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
14779                                                                if (subquerys != null && !subquerys.isEmpty()) {
14780                                                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
14781                                                                }
14782
14783                                                                analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
14784
14785                                                                List<TParseTreeNode> constants = visitor.getConstants();
14786                                                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
14787                                                        } else {
14788                                                                if (column.getFieldAttr() != null && isStructColumn(column.getFieldAttr())) {
14789                                                                        Table table = modelFactory.createTable(column.getFieldAttr().getSourceTable());
14790                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
14791                                                                                TObjectName columnName = new TObjectName();
14792                                                                                if (table.getColumns().get(j).getName().equals(table.getAlias())) {
14793                                                                                        if (!SQLUtil.isEmpty(column.getColumnAlias())) {
14794                                                                                                columnName.setString(column.getColumnAlias());
14795                                                                                        } else {
14796                                                                                                columnName.setString(table.getColumns().get(j).getName());
14797                                                                                        }
14798                                                                                } else {
14799                                                                                        columnName.setString(
14800                                                                                                        table.getAlias() + "." + table.getColumns().get(j).getName());
14801                                                                                }
14802                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
14803                                                                                                columnName);
14804                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
14805                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
14806                                                                                relationship.addSource(
14807                                                                                                new TableColumnRelationshipElement(table.getColumns().get(j)));
14808                                                                        }
14809                                                                } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.struct_t) {
14810                                                                        Function function = (Function) createFunction(column.getExpr().getFunctionCall());
14811                                                                        String functionName = getResultSetName(function);
14812                                                                        for (int j = 0; j < function.getColumns().size(); j++) {
14813                                                                                TObjectName columnName = new TObjectName();
14814                                                                                if (column.getAliasClause() != null) {
14815                                                                                        columnName.setString(column.getAliasClause() + "."
14816                                                                                                        + function.getColumns().get(j).getName());
14817                                                                                }
14818                                                                                else {
14819                                                                                        columnName.setString(functionName + "."
14820                                                                                                        + function.getColumns().get(j).getName());
14821                                                                                }
14822                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
14823                                                                                                columnName);
14824                                                                                resultColumn.setStruct(true);
14825                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
14826                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
14827                                                                                relationship.addSource(
14828                                                                                                new ResultColumnRelationshipElement(function.getColumns().get(j)));
14829                                                                        }
14830                                                                } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.array_t) {
14831                                                                        Function function = (Function) createFunction(column.getExpr().getFunctionCall());
14832                                                                        String functionName = getResultSetName(function);
14833                                                                        for (int j = 0; j < function.getColumns().size(); j++) {
14834                                                                                TObjectName columnName = new TObjectName();
14835                                                                                if (column.getAliasClause() != null) {
14836                                                                                        columnName.setString(column.getAliasClause() + "."
14837                                                                                                        + getColumnNameOnly(function.getColumns().get(j).getName()));
14838                                                                                }
14839                                                                                else {
14840                                                                                        columnName.setString(functionName + "."
14841                                                                                                        + getColumnNameOnly(function.getColumns().get(j).getName()));
14842                                                                                }
14843                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
14844                                                                                                columnName);
14845                                                                                resultColumn.setStruct(true);
14846                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
14847                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
14848                                                                                relationship.addSource(
14849                                                                                                new ResultColumnRelationshipElement(function.getColumns().get(j)));
14850                                                                        }
14851                                                                } else if (column.getExpr().getExprList() != null && column.getExpr().getExpressionType() == EExpressionType.array_t) {
14852                                                                        if(column.getExpr().getObjectOperand()!=null) {
14853                                                                                TObjectName exprColumnName = column.getExpr().getObjectOperand();
14854                                                                                Table table = modelFactory.createTable(exprColumnName.getSourceTable());
14855                                                                                for (int z = 0; z < table.getColumns().size(); z++) {
14856                                                                                        TableColumn tableColumn = table.getColumns().get(z);
14857                                                                                        if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) {
14858                                                                                                TObjectName columnName = new TObjectName();
14859                                                                                                if (column.getAliasClause() != null) {
14860                                                                                                        columnName.setString(column.getAliasClause().toString());
14861                                                                                                } else {
14862                                                                                                        columnName
14863                                                                                                                        .setString(getColumnNameOnly(columnName.toString()));
14864                                                                                                }
14865                                                                                                ResultColumn resultColumn = modelFactory
14866                                                                                                                .createResultColumn(resultSetModel, columnName);
14867                                                                                                resultColumn.setStruct(true);
14868                                                                                                DataFlowRelationship relationship = modelFactory
14869                                                                                                                .createDataFlowRelation();
14870                                                                                                relationship.setTarget(
14871                                                                                                                new ResultColumnRelationshipElement(resultColumn));
14872                                                                                                relationship.addSource(new TableColumnRelationshipElement(
14873                                                                                                                tableColumn));
14874                                                                                        }
14875                                                                                }
14876                                                                        }
14877                                                                        else {
14878                                                                                for (int j = 0; j < column.getExpr().getExprList().size(); j++) {
14879                                                                                        TExpression expression = column.getExpr().getExprList().getExpression(j);
14880                                                                                        if(expression.getExpressionType() == EExpressionType.function_t) {
14881                                                                                                Function function = (Function)createFunction(expression.getFunctionCall());
14882                                                                                                String functionName = getResultSetName(function);
14883                                                                                                if (function != null && function.getColumns() != null) {
14884                                                                                                        for (int x = 0; x < function.getColumns().size(); x++) {
14885                                                                                                                TObjectName columnName = new TObjectName();
14886                                                                                                                if (column.getAliasClause() != null) {
14887                                                                                                                        columnName.setString(column.getAliasClause() + ".array."
14888                                                                                                                                        + getColumnNameOnly(
14889                                                                                                                                                        function.getColumns().get(x).getName()));
14890                                                                                                                } else {
14891                                                                                                                        columnName.setString(
14892                                                                                                                                        functionName + ".array." + getColumnNameOnly(
14893                                                                                                                                                        function.getColumns().get(x).getName()));
14894                                                                                                                }
14895                                                                                                                ResultColumn resultColumn = modelFactory
14896                                                                                                                                .createResultColumn(resultSetModel, columnName);
14897                                                                                                                resultColumn.setStruct(true);
14898                                                                                                                DataFlowRelationship relationship = modelFactory
14899                                                                                                                                .createDataFlowRelation();
14900                                                                                                                relationship.setTarget(
14901                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
14902                                                                                                                relationship.addSource(new ResultColumnRelationshipElement(
14903                                                                                                                                function.getColumns().get(x)));
14904                                                                                                        }
14905                                                                                                }
14906                                                                                        }
14907                                                                                        else if(expression.getExpressionType() == EExpressionType.simple_object_name_t) {
14908                                                                                                TObjectName exprColumnName = expression.getObjectOperand();
14909                                                                                                Table table = modelFactory.createTable(exprColumnName.getSourceTable());
14910                                                                                                for (int z = 0; z < table.getColumns().size(); z++) {
14911                                                                                                        TableColumn tableColumn = table.getColumns().get(z);
14912                                                                                                        if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) {
14913                                                                                                                TObjectName columnName = new TObjectName();
14914                                                                                                                if (column.getAliasClause() != null) {
14915                                                                                                                        columnName.setString(column.getAliasClause().toString());
14916                                                                                                                } else {
14917                                                                                                                        columnName
14918                                                                                                                                        .setString(getColumnNameOnly(columnName.toString()));
14919                                                                                                                }
14920                                                                                                                ResultColumn resultColumn = modelFactory
14921                                                                                                                                .createResultColumn(resultSetModel, columnName);
14922                                                                                                                resultColumn.setStruct(true);
14923                                                                                                                DataFlowRelationship relationship = modelFactory
14924                                                                                                                                .createDataFlowRelation();
14925                                                                                                                relationship.setTarget(
14926                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
14927                                                                                                                relationship.addSource(new TableColumnRelationshipElement(
14928                                                                                                                                tableColumn));
14929                                                                                                        }
14930                                                                                                }
14931                                                                                        }
14932                                                                                }
14933                                                                        }
14934                                                                } else {
14935                                                                        if ("*".equals(column.getColumnNameOnly())) {
14936                                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
14937                                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
14938                                                                                if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) {
14939                                                                                        for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) {
14940                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
14941                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
14942                                                                                        }
14943                                                                                }
14944                                                                                
14945                                                                                TObjectName columnObject = column.getFieldAttr();
14946                                                                                List<TTable> sourceTables = columnObject.getSourceTableList();
14947                                                                                if (sourceTables != null && !sourceTables.isEmpty()) {
14948                                                                                        boolean[] determine = new boolean[sourceTables.size()];
14949                                                                                        for (int k = 0; k < sourceTables.size(); k++) {
14950                                                                                                TTable sourceTable = sourceTables.get(k);
14951                                                                                                Object tableModel = modelManager.getModel(sourceTable);
14952                                                                                                if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
14953                                                                                                        Table table = (Table) tableModel;
14954                                                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
14955                                                                                                                TableColumn tableColumn = table.getColumns().get(j);
14956                                                                                                                if (column.getExceptColumnList() != null) {
14957                                                                                                                        boolean except = false;
14958                                                                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
14959                                                                                                                                if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) {
14960                                                                                                                                        except = true;
14961                                                                                                                                        break;
14962                                                                                                                                }
14963                                                                                                                        }
14964                                                                                                                        if (!except && tableColumn.isStruct()) {
14965                                                                                                                                List<String> names = SQLUtil
14966                                                                                                                                                .parseNames(tableColumn.getName());
14967                                                                                                                                for (String name : names) {
14968                                                                                                                                        for (TObjectName objectName : column
14969                                                                                                                                                        .getExceptColumnList()) {
14970                                                                                                                                                if (getColumnName(objectName.toString())
14971                                                                                                                                                                .equals(getColumnName(name))) {
14972                                                                                                                                                        except = true;
14973                                                                                                                                                        break;
14974                                                                                                                                                }
14975                                                                                                                                        }
14976                                                                                                                                        if (except) {
14977                                                                                                                                                break;
14978                                                                                                                                        }
14979                                                                                                                                }
14980                                                                                                                        }
14981                                                                                                                        if(except){
14982                                                                                                                                continue;
14983                                                                                                                        }
14984                                                                                                                }
14985                                                                                                                
14986                                                                                                                if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
14987                                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
14988                                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
14989                                                                                                                        Transform transform = new Transform();
14990                                                                                                                        transform.setType(Transform.EXPRESSION);
14991                                                                                                                        TObjectName expression = new TObjectName();
14992                                                                                                                        expression.setString(expr.first);
14993                                                                                                                transform.setCode(expression);
14994                                                                                                                        resultColumn.setTransform(transform);
14995                                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
14996                                                                                                                }
14997                                                                                                                else {
14998                                                                                                                        String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName());
14999                                                                                                                        //bigquery
15000                                                                                                                        boolean exist = false;
15001                                                                                                                        if (!columnName.matches("(?i)f\\d+_")) {
15002                                                                                                                                if (!keyMap.containsKey(columnName)) {
15003                                                                                                                                        keyMap.put(columnName, new AtomicInteger(0));
15004                                                                                                                                } else {
15005                                                                                                                                        while (columnNames.contains(columnName)) {
15006                                                                                                                                                if(stmt.toString().matches("(?is).*using\\s*\\(\\s*"+columnName+"\\s*\\).*")) {
15007                                                                                                                                                        exist = true;
15008                                                                                                                                                        break;
15009                                                                                                                                                }
15010                                                                                                                                                else {
15011                                                                                                                                                        int index = keyMap.get(columnName)
15012                                                                                                                                                                        .incrementAndGet();
15013                                                                                                                                                        columnName = columnName + index;
15014                                                                                                                                                }
15015                                                                                                                                        }
15016                                                                                                                                }
15017                                                                                                                                columnNames.add(columnName);
15018                                                                                                                        }
15019                                                                                                                        if (exist) {
15020                                                                                                                                String targetColumn = columnName;
15021                                                                                                                                DataFlowRelationship relation = modelFactory
15022                                                                                                                                                .createDataFlowRelation();
15023                                                                                                                                relation.setEffectType(EffectType.select);
15024                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(
15025                                                                                                                                                resultSetModel.getColumns().stream()
15026                                                                                                                                                                .filter(t -> t.getName()
15027                                                                                                                                                                                .equalsIgnoreCase(targetColumn))
15028                                                                                                                                                                .findFirst().get()));
15029                                                                                                                                relation.addSource(new TableColumnRelationshipElement(
15030                                                                                                                                                tableColumn));
15031                                                                                                                                continue;
15032                                                                                                                        }
15033                                                                                                                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName())
15034                                                                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) {
15035                                                                                                                                columnName = tableColumn.getName();
15036                                                                                                                        }
15037                                                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName);
15038                                                                                                                        resultColumn.setStruct(tableColumn.isStruct());
15039                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15040                                                                                                                        relation.setEffectType(EffectType.select);
15041                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15042                                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
15043                                                                                                                }
15044                                                                                                        }
15045                                                                                                        determine[k] = true;
15046                                                                                                        continue;
15047                                                                                                }
15048                                                                                                else if (tableModel instanceof ResultSet && ((ResultSet) tableModel).isDetermined()) {
15049                                                                                                        ResultSet table = (ResultSet) tableModel;
15050                                                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
15051                                                                                                                ResultColumn tableColumn = table.getColumns().get(j);
15052                                                                                                                if (column.getExceptColumnList() != null) {
15053                                                                                                                        boolean except = false;
15054                                                                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
15055                                                                                                                                if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) {
15056                                                                                                                                        except = true;
15057                                                                                                                                        break;
15058                                                                                                                                }
15059                                                                                                                        }
15060                                                                                                                        if (!except && tableColumn.isStruct()) {
15061                                                                                                                                List<String> names = SQLUtil
15062                                                                                                                                                .parseNames(tableColumn.getName());
15063                                                                                                                                for (String name : names) {
15064                                                                                                                                        for (TObjectName objectName : column
15065                                                                                                                                                        .getExceptColumnList()) {
15066                                                                                                                                                if (getColumnName(objectName.toString())
15067                                                                                                                                                                .equals(getColumnName(name))) {
15068                                                                                                                                                        except = true;
15069                                                                                                                                                        break;
15070                                                                                                                                                }
15071                                                                                                                                        }
15072                                                                                                                                        if (except) {
15073                                                                                                                                                break;
15074                                                                                                                                        }
15075                                                                                                                                }
15076                                                                                                                        }
15077                                                                                                                        if(except){
15078                                                                                                                                continue;
15079                                                                                                                        }
15080                                                                                                                }
15081                                                                                                                if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
15082                                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
15083                                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
15084                                                                                                                        Transform transform = new Transform();
15085                                                                                                                        transform.setType(Transform.EXPRESSION);
15086                                                                                                                        TObjectName expression = new TObjectName();
15087                                                                                                                        expression.setString(expr.first);
15088                                                                                                                transform.setCode(expression);
15089                                                                                                                        resultColumn.setTransform(transform);
15090                                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
15091                                                                                                                }
15092                                                                                                                else if(tableColumn.getRefColumnName()!=null) {
15093                                                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, tableColumn.getRefColumnName());
15094                                                                                                                        if(tableColumn.isStruct()) {
15095                                                                                                                                resultColumn.setStruct(true);
15096                                                                                                                        }
15097                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15098                                                                                                                        relation.setEffectType(EffectType.select);
15099                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15100                                                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15101                                                                                                                }
15102                                                                                                                else {
15103                                                                                                                        String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName());
15104                                                                                                                        //bigquery
15105                                                                                                                        if (!columnName.matches("(?i)f\\d+_")) {
15106                                                                                                                                if (!keyMap.containsKey(columnName)) {
15107                                                                                                                                        keyMap.put(columnName, new AtomicInteger(0));
15108                                                                                                                                } else {
15109                                                                                                                                        while (columnNames.contains(columnName)) {
15110                                                                                                                                                int index = keyMap.get(columnName)
15111                                                                                                                                                                .incrementAndGet();
15112                                                                                                                                                columnName = columnName + index;
15113                                                                                                                                        }
15114                                                                                                                                }
15115                                                                                                                                columnNames.add(columnName);
15116                                                                                                                        }
15117                                                                                                                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName())
15118                                                                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) {
15119                                                                                                                                columnName = tableColumn.getName();
15120                                                                                                                        }
15121                                                                                                                        if (modelManager.getModel(column) instanceof ResultColumn) {
15122                                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15123                                                                                                                                relation.setEffectType(EffectType.select);
15124                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement((ResultColumn)modelManager.getModel(column)));
15125                                                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15126                                                                                                                        }
15127                                                                                                                        else {
15128                                                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName);
15129                                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15130                                                                                                                                relation.setEffectType(EffectType.select);
15131                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15132                                                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15133                                                                                                                        }
15134                                                                                                                }
15135                                                                                                        }
15136                                                                                                        determine[k] = true;
15137                                                                                                        continue;
15138                                                                                                }
15139                                                                                                else {
15140                                                                                                        ResultColumn resultColumn = modelFactory
15141                                                                                                                        .createResultColumn(resultSetModel, column);
15142                                                                                                        if (tableModel instanceof Function) {
15143                                                                                                
15144                                                                                                        } else {
15145                                                                                                                TObjectName[] columns = modelManager
15146                                                                                                                                .getTableColumns(sourceTable);
15147                                                                                                                for (int j = 0; j < columns.length; j++) {
15148                                                                                                                        TObjectName columnName = columns[j];
15149                                                                                                                        if (columnName == null
15150                                                                                                                                        || "*".equals(getColumnName(columnName))) {
15151                                                                                                                                continue;
15152                                                                                                                        }
15153                                                                                                                        if (isStructColumn(columnName)) {
15154                                                                                                                                continue;
15155                                                                                                                        }
15156
15157                                                                                                                        resultColumn.bindStarLinkColumn(columnName);
15158                                                                                                                        if (column.getExceptColumnList() != null) {
15159                                                                                                                                for (TObjectName objectName : column
15160                                                                                                                                                .getExceptColumnList()) {
15161                                                                                                                                        resultColumn.unbindStarLinkColumn(objectName);
15162                                                                                                                                }
15163                                                                                                                        }
15164                                                                                                                }
15165                                                                                                                if (tableModel instanceof ResultSet) {
15166                                                                                                                        ResultSet queryTable = (ResultSet) tableModel;
15167                                                                                                                        if (!containStarColumn(queryTable)) {
15168                                                                                                                                resultColumn.setShowStar(false);
15169                                                                                                                        }
15170                                                                                                                }
15171                                                                                                                if (tableModel instanceof Table) {
15172                                                                                                                        Table table = (Table) tableModel;
15173                                                                                                                        if (table.isCreateTable()) {
15174                                                                                                                                resultColumn.setShowStar(false);
15175                                                                                                                        }
15176                                                                                                                }
15177                                                                                                        }
15178                                                                                                }
15179                                                                                        }
15180                                                                                        if(!Arrays.toString(determine).contains("false")) {
15181                                                                                                continue;
15182                                                                                        }
15183                                                                                } else {
15184                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
15185                                                                                        TTableList tables = stmt.getTables();
15186                                                                                        for (int k = 0; k < tables.size(); k++) {
15187                                                                                                TTable table = tables.getTable(k);
15188                                                                                                TObjectName[] columns = modelManager.getTableColumns(table);
15189                                                                                                for (int j = 0; j < columns.length; j++) {
15190                                                                                                        TObjectName columnName = columns[j];
15191                                                                                                        if (columnName == null) {
15192                                                                                                                continue;
15193                                                                                                        }
15194                                                                                                        if ("*".equals(getColumnName(columnName))) {
15195                                                                                                                if (modelManager.getModel(table) instanceof Table) {
15196                                                                                                                        Table tableModel = (Table) modelManager.getModel(table);
15197                                                                                                                        if (tableModel != null
15198                                                                                                                                        && !tableModel.getColumns().isEmpty()) {
15199                                                                                                                                for (TableColumn item : tableModel.getColumns()) {
15200                                                                                                                                        resultColumn
15201                                                                                                                                                        .bindStarLinkColumn(item.getColumnObject());
15202                                                                                                                                        if (table.getSubquery() == null
15203                                                                                                                                                        && table.getCTE() == null
15204                                                                                                                                                        && !tableModel.isCreateTable()) {
15205                                                                                                                                                resultColumn.setShowStar(true);
15206                                                                                                                                        }
15207                                                                                                                                }
15208                                                                                                                        }
15209                                                                                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
15210                                                                                                                        QueryTable tableModel = (QueryTable) modelManager
15211                                                                                                                                        .getModel(table);
15212                                                                                                                        if (tableModel != null
15213                                                                                                                                        && !tableModel.getColumns().isEmpty()) {
15214                                                                                                                                for (ResultColumn item : tableModel.getColumns()) {
15215                                                                                                                                        if (item.hasStarLinkColumn()) {
15216                                                                                                                                                for (TObjectName starLinkColumn : item
15217                                                                                                                                                                .getStarLinkColumnList()) {
15218                                                                                                                                                        resultColumn
15219                                                                                                                                                                        .bindStarLinkColumn(starLinkColumn);
15220                                                                                                                                                }
15221                                                                                                                                        } else if (item
15222                                                                                                                                                        .getColumnObject() instanceof TObjectName) {
15223                                                                                                                                                resultColumn.bindStarLinkColumn(
15224                                                                                                                                                                (TObjectName) item.getColumnObject());
15225                                                                                                                                        } else if (item
15226                                                                                                                                                        .getColumnObject() instanceof TResultColumn) {
15227                                                                                                                                                TResultColumn queryTableColumn = (TResultColumn) item
15228                                                                                                                                                                .getColumnObject();
15229                                                                                                                                                TObjectName tableColumnObject = queryTableColumn
15230                                                                                                                                                                .getFieldAttr();
15231                                                                                                                                                if (tableColumnObject != null) {
15232                                                                                                                                                        resultColumn.bindStarLinkColumn(
15233                                                                                                                                                                        tableColumnObject);
15234                                                                                                                                                } else if (queryTableColumn
15235                                                                                                                                                                .getAliasClause() != null) {
15236                                                                                                                                                        resultColumn.bindStarLinkColumn(
15237                                                                                                                                                                        queryTableColumn.getAliasClause()
15238                                                                                                                                                                                        .getAliasName());
15239                                                                                                                                                }
15240                                                                                                                                        }
15241                                                                                                                                }
15242                                                                                                                        }
15243                                                                                                                }
15244                                                                                                                continue;
15245                                                                                                        }
15246                                                                                                        resultColumn.bindStarLinkColumn(columnName);
15247                                                                                                }
15248                                                                                        }
15249                                                                                }
15250                                                                                isDetermined = false;
15251                                                                        }
15252                                                                        else {
15253                                                                                if(column.getAliasClause()!=null && column.getAliasClause().getColumns()!=null) {
15254                                                                                        for(TObjectName aliasColumn: column.getAliasClause().getColumns()) {
15255                                                                                                modelFactory.createResultColumn(resultSetModel, aliasColumn);
15256                                                                                        }
15257                                                                                }
15258                                                                                else {
15259                                                                                        modelFactory.createResultColumn(resultSetModel, column);
15260                                                                                }
15261                                                                        }
15262                                                                        analyzeResultColumn(column, EffectType.select);
15263                                                                }
15264                                                        }
15265                                                }
15266                                                if (isDetermined) {
15267                                                        resultSetModel.setDetermined(isDetermined);
15268                                                }
15269                                        }
15270
15271                                        TSelectSqlStatement parent = getParentSetSelectStmt(stmt);
15272                                        if (parent != null && parent.getSetOperatorType() != ESetOperatorType.none) {
15273                                                ResultSet resultSetModel = modelFactory.createResultSet(stmt, false);
15274                                                if(queryModel == null) {
15275                                                        queryModel = resultSetModel;
15276                                                } 
15277
15278                                                createPseudoImpactRelation(stmt, resultSetModel, EffectType.select);
15279
15280                                                boolean isDetermined = true;
15281                                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
15282                                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
15283                                                        if ("*".equals(column.getColumnNameOnly())) {
15284                                                                
15285                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
15286                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
15287                                                                if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) {
15288                                                                        for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) {
15289                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
15290                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
15291                                                                        }
15292                                                                }
15293                                                                
15294                                                                TObjectName columnObject = column.getFieldAttr();
15295                                                                TTable sourceTable = columnObject.getSourceTable();
15296                                                                if (sourceTable != null) {
15297                                                                        Object tableModel = modelManager.getModel(sourceTable);
15298                                                                        if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
15299                                                                                Table table = (Table) tableModel;
15300                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
15301                                                                                        TableColumn tableColumn = table.getColumns().get(j);
15302                                                                                        if (column.getExceptColumnList() != null) {
15303                                                                                                boolean except = false;
15304                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
15305                                                                                                        if (getColumnName(objectName.toString())
15306                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
15307                                                                                                                except = true;
15308                                                                                                                break;
15309                                                                                                        }
15310                                                                                                }
15311                                                                                                if (!except && tableColumn.isStruct()) {
15312                                                                                                        List<String> names = SQLUtil
15313                                                                                                                        .parseNames(tableColumn.getName());
15314                                                                                                        for (String name : names) {
15315                                                                                                                for (TObjectName objectName : column
15316                                                                                                                                .getExceptColumnList()) {
15317                                                                                                                        if (getColumnName(objectName.toString())
15318                                                                                                                                        .equals(getColumnName(name))) {
15319                                                                                                                                except = true;
15320                                                                                                                                break;
15321                                                                                                                        }
15322                                                                                                                }
15323                                                                                                                if (except) {
15324                                                                                                                        break;
15325                                                                                                                }
15326                                                                                                        }
15327                                                                                                }
15328                                                                                                if (except) {
15329                                                                                                        continue;
15330                                                                                                }
15331                                                                                        }
15332                                                                                        
15333                                                                                        if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
15334                                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
15335                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
15336                                                                                                Transform transform = new Transform();
15337                                                                                                transform.setType(Transform.EXPRESSION);
15338                                                                                                TObjectName expression = new TObjectName();
15339                                                                                                expression.setString(expr.first);
15340                                                                                        transform.setCode(expression);
15341                                                                                                resultColumn.setTransform(transform);
15342                                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
15343                                                                                        }
15344                                                                                        else {
15345                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
15346                                                                                                                resultSetModel, column, tableColumn.getName());
15347                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15348                                                                                                relation.setEffectType(EffectType.select);
15349                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15350                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
15351                                                                                        }
15352                                                                                }
15353                                                                                continue;
15354                                                                        } else if (tableModel instanceof ResultSet
15355                                                                                        && ((ResultSet) tableModel).isDetermined()) {
15356                                                                                ResultSet table = (ResultSet) tableModel;
15357                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
15358                                                                                        ResultColumn tableColumn = table.getColumns().get(j);
15359                                                                                        if (column.getExceptColumnList() != null) {
15360                                                                                                boolean except = false;
15361                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
15362                                                                                                        if (getColumnName(objectName.toString())
15363                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
15364                                                                                                                except = true;
15365                                                                                                                break;
15366                                                                                                        }
15367                                                                                                }
15368                                                                                                if (!except && tableColumn.isStruct()) {
15369                                                                                                        List<String> names = SQLUtil
15370                                                                                                                        .parseNames(tableColumn.getName());
15371                                                                                                        for (String name : names) {
15372                                                                                                                for (TObjectName objectName : column
15373                                                                                                                                .getExceptColumnList()) {
15374                                                                                                                        if (getColumnName(objectName.toString())
15375                                                                                                                                        .equals(getColumnName(name))) {
15376                                                                                                                                except = true;
15377                                                                                                                                break;
15378                                                                                                                        }
15379                                                                                                                }
15380                                                                                                                if (except) {
15381                                                                                                                        break;
15382                                                                                                                }
15383                                                                                                        }
15384                                                                                                }
15385                                                                                                if (except) {
15386                                                                                                        continue;
15387                                                                                                }
15388                                                                                        }
15389                                                                                        
15390                                                                                        if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
15391                                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
15392                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
15393                                                                                                Transform transform = new Transform();
15394                                                                                                transform.setType(Transform.EXPRESSION);
15395                                                                                                TObjectName expression = new TObjectName();
15396                                                                                                expression.setString(expr.first);
15397                                                                                        transform.setCode(expression);
15398                                                                                                resultColumn.setTransform(transform);
15399                                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
15400                                                                                        }
15401                                                                                        else if (tableColumn.getRefColumnName() != null) {
15402                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
15403                                                                                                                (ResultSet)queryModel, column, tableColumn.getRefColumnName());
15404                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15405                                                                                                relation.setEffectType(EffectType.select);
15406                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15407                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15408                                                                                        } else {
15409                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
15410                                                                                                                resultSetModel, column, tableColumn.getName());
15411                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15412                                                                                                relation.setEffectType(EffectType.select);
15413                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15414                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15415                                                                                        }
15416                                                                                }
15417                                                                                continue;
15418                                                                        }
15419                                                                        else {
15420                                                                                isDetermined = false;
15421                                                                        }
15422                                                                }
15423                                                                
15424                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
15425                                                                
15426                                                                if (columnObject.getTableToken() != null && sourceTable != null) {
15427                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
15428                                                                        for (int j = 0; j < columns.length; j++) {
15429                                                                                TObjectName columnName = columns[j];
15430                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
15431                                                                                        continue;
15432                                                                                }
15433                                                                                resultColumn.bindStarLinkColumn(columnName);
15434                                                                        }
15435
15436                                                                        if (modelManager.getModel(sourceTable) instanceof Table) {
15437                                                                                Table tableModel = (Table) modelManager.getModel(sourceTable);
15438                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
15439                                                                                        for (TableColumn item : tableModel.getColumns()) {
15440                                                                                                if ("*".equals(getColumnName(item.getColumnObject()))) {
15441                                                                                                        continue;
15442                                                                                                }
15443                                                                                                resultColumn.bindStarLinkColumn(item.getColumnObject());
15444                                                                                        }
15445                                                                                }
15446                                                                        } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
15447                                                                                QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
15448                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
15449                                                                                        for (ResultColumn item : tableModel.getColumns()) {
15450                                                                                                if (item.hasStarLinkColumn()) {
15451                                                                                                        for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
15452                                                                                                                if ("*".equals(getColumnName(starLinkColumn))) {
15453                                                                                                                        continue;
15454                                                                                                                }
15455                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
15456                                                                                                        }
15457                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
15458                                                                                                        TObjectName starLinkColumn = (TObjectName) item.getColumnObject();
15459                                                                                                        if ("*".equals(getColumnName(starLinkColumn))) {
15460                                                                                                                continue;
15461                                                                                                        }
15462                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
15463                                                                                                }
15464                                                                                        }
15465                                                                                }
15466                                                                        }
15467
15468                                                                } else {
15469                                                                        TTableList tables = stmt.getTables();
15470                                                                        for (int k = 0; k < tables.size(); k++) {
15471                                                                                TTable table = tables.getTable(k);
15472                                                                                TObjectName[] columns = modelManager.getTableColumns(table);
15473                                                                                for (int j = 0; j < columns.length; j++) {
15474                                                                                        TObjectName columnName = columns[j];
15475                                                                                        if (columnName == null) {
15476                                                                                                continue;
15477                                                                                        }
15478                                                                                        if ("*".equals(getColumnName(columnName))) {
15479                                                                                                if (modelManager.getModel(table) instanceof Table) {
15480                                                                                                        Table tableModel = (Table) modelManager.getModel(table);
15481                                                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
15482                                                                                                                for (TableColumn item : tableModel.getColumns()) {
15483                                                                                                                        resultColumn.bindStarLinkColumn(item.getColumnObject());
15484                                                                                                                }
15485                                                                                                        }
15486                                                                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
15487                                                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(table);
15488                                                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
15489                                                                                                                for (ResultColumn item : tableModel.getColumns()) {
15490                                                                                                                        if (item.hasStarLinkColumn()) {
15491                                                                                                                                for (TObjectName starLinkColumn : item
15492                                                                                                                                                .getStarLinkColumnList()) {
15493                                                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
15494                                                                                                                                }
15495                                                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
15496                                                                                                                                resultColumn.bindStarLinkColumn(
15497                                                                                                                                                (TObjectName) item.getColumnObject());
15498                                                                                                                        } else if (item
15499                                                                                                                                        .getColumnObject() instanceof TResultColumn) {
15500                                                                                                                                TResultColumn queryTableColumn = (TResultColumn) item
15501                                                                                                                                                .getColumnObject();
15502                                                                                                                                TObjectName tableColumnObject = queryTableColumn
15503                                                                                                                                                .getFieldAttr();
15504                                                                                                                                if (tableColumnObject != null) {
15505                                                                                                                                        resultColumn.bindStarLinkColumn(tableColumnObject);
15506                                                                                                                                } else if (queryTableColumn.getAliasClause() != null) {
15507                                                                                                                                        resultColumn.bindStarLinkColumn(queryTableColumn
15508                                                                                                                                                        .getAliasClause().getAliasName());
15509                                                                                                                                }
15510                                                                                                                        }
15511                                                                                                                }
15512                                                                                                        }
15513                                                                                                }
15514
15515                                                                                                continue;
15516                                                                                        }
15517                                                                                        resultColumn.bindStarLinkColumn(columnName);
15518                                                                                }
15519                                                                        }
15520                                                                }
15521                                                        }
15522                                                        else {
15523                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
15524                                                        }
15525                                                        analyzeResultColumn(column, EffectType.select);
15526
15527                                                }
15528                                                
15529                                                resultSetModel.setDetermined(isDetermined);
15530                                        }
15531                                } else {
15532                                        for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
15533                                                TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
15534
15535                                                if (!(queryModel instanceof ResultSet)) {
15536                                                        continue;
15537                                                }
15538                                                
15539                                                ResultSet resultSetModel = (ResultSet)queryModel;
15540                                                        
15541                                                if ("*".equals(column.getColumnNameOnly())) {
15542                                                        TObjectName columnObject = column.getFieldAttr();
15543                                                        TTable sourceTable = columnObject.getSourceTable();
15544                                                        if (column.toString().indexOf(".") == -1 && stmt.getTables().size() > 1) {
15545                                                                sourceTable = null;
15546                                                        }
15547                                                        if (sourceTable != null) {
15548                                                                {
15549                                                                        Object tableModel = modelManager.getModel(sourceTable);
15550                                                                        if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
15551                                                                                Table table = (Table) tableModel;
15552                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
15553                                                                                        TableColumn tableColumn = table.getColumns().get(j);
15554                                                                                        if (column.getExceptColumnList() != null) {
15555                                                                                                boolean except = false;
15556                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
15557                                                                                                        if (getColumnName(objectName.toString())
15558                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
15559                                                                                                                except = true;
15560                                                                                                                break;
15561                                                                                                        }
15562                                                                                                }
15563                                                                                                if (!except && tableColumn.isStruct()) {
15564                                                                                                        List<String> names = SQLUtil
15565                                                                                                                        .parseNames(tableColumn.getName());
15566                                                                                                        for (String name : names) {
15567                                                                                                                for (TObjectName objectName : column
15568                                                                                                                                .getExceptColumnList()) {
15569                                                                                                                        if (getColumnName(objectName.toString())
15570                                                                                                                                        .equals(getColumnName(name))) {
15571                                                                                                                                except = true;
15572                                                                                                                                break;
15573                                                                                                                        }
15574                                                                                                                }
15575                                                                                                                if (except) {
15576                                                                                                                        break;
15577                                                                                                                }
15578                                                                                                        }
15579                                                                                                }
15580                                                                                                if (except) {
15581                                                                                                        continue;
15582                                                                                                }
15583                                                                                        }
15584                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(
15585                                                                                                        resultSetModel, column, tableColumn.getName());
15586                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15587                                                                                        relation.setEffectType(EffectType.select);
15588                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15589                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
15590                                                                                }
15591                                                                                if(stmt.getResultColumnList().size() == 1) {
15592                                                                                        resultSetModel.setDetermined(true);
15593                                                                                }
15594                                                                                else {
15595                                                                                        int starCount = 0;
15596                                                                                        for (int j = 0; j < stmt.getResultColumnList().size(); j++) {
15597                                                                                                if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly()
15598                                                                                                                .endsWith("*")) {
15599                                                                                                        starCount += 1;
15600                                                                                                }
15601                                                                                        }
15602                                                                                        if (starCount <= 1) {
15603                                                                                                resultSetModel.setDetermined(true);
15604                                                                                        }
15605                                                                                }
15606                                                                                continue;
15607                                                                        } else if (tableModel instanceof ResultSet
15608                                                                                        && ((ResultSet) tableModel).isDetermined()) {
15609                                                                                ResultSet table = (ResultSet) tableModel;
15610                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
15611                                                                                        ResultColumn tableColumn = table.getColumns().get(j);
15612                                                                                        if (column.getExceptColumnList() != null) {
15613                                                                                                boolean except = false;
15614                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
15615                                                                                                        if (getColumnName(objectName.toString())
15616                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
15617                                                                                                                except = true;
15618                                                                                                                break;
15619                                                                                                        }
15620                                                                                                }
15621                                                                                                if (!except && tableColumn.isStruct()) {
15622                                                                                                        List<String> names = SQLUtil
15623                                                                                                                        .parseNames(tableColumn.getName());
15624                                                                                                        for (String name : names) {
15625                                                                                                                for (TObjectName objectName : column
15626                                                                                                                                .getExceptColumnList()) {
15627                                                                                                                        if (getColumnName(objectName.toString())
15628                                                                                                                                        .equals(getColumnName(name))) {
15629                                                                                                                                except = true;
15630                                                                                                                                break;
15631                                                                                                                        }
15632                                                                                                                }
15633                                                                                                                if (except) {
15634                                                                                                                        break;
15635                                                                                                                }
15636                                                                                                        }
15637                                                                                                }
15638                                                                                                if (except) {
15639                                                                                                        continue;
15640                                                                                                }
15641                                                                                        }
15642                                                                                        if (tableColumn.getRefColumnName() != null) {
15643                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
15644                                                                                                                (ResultSet)queryModel, column, tableColumn.getRefColumnName());
15645                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15646                                                                                                relation.setEffectType(EffectType.select);
15647                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15648                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15649                                                                                        } else {
15650                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
15651                                                                                                                resultSetModel, column, tableColumn.getName());
15652                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15653                                                                                                relation.setEffectType(EffectType.select);
15654                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
15655                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
15656                                                                                        }
15657                                                                                }
15658                                                                                if(stmt.getResultColumnList().size() == 1) {
15659                                                                                        resultSetModel.setDetermined(true);
15660                                                                                }
15661                                                                                else {
15662                                                                                        int starCount = 0;
15663                                                                                        for (int j = 0; j < stmt.getResultColumnList().size(); j++) {
15664                                                                                                if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly()
15665                                                                                                                .endsWith("*")) {
15666                                                                                                        starCount += 1;
15667                                                                                                }
15668                                                                                        }
15669                                                                                        if (starCount <= 1) {
15670                                                                                                resultSetModel.setDetermined(true);
15671                                                                                        }
15672                                                                                }
15673                                                                                continue;
15674                                                                        }
15675                                                                }
15676                                                                
15677                                                                ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
15678                                                                if (modelManager.getModel(sourceTable) instanceof Table) {
15679                                                                        Table tableModel = (Table) modelManager.getModel(sourceTable);
15680                                                                        if (tableModel != null) {
15681                                                                                modelFactory.createTableColumn(tableModel, columnObject, false);
15682                                                                        }
15683                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
15684                                                                        for (int j = 0; j < columns.length; j++) {
15685                                                                                TObjectName columnName = columns[j];
15686                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
15687                                                                                        continue;
15688                                                                                }
15689                                                                                resultColumn.bindStarLinkColumn(columnName);
15690                                                                        }
15691
15692                                                                        if (tableModel.getColumns() != null) {
15693                                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
15694                                                                                        TableColumn tableColumn = tableModel.getColumns().get(j);
15695                                                                                        TObjectName columnName = tableColumn.getColumnObject();
15696                                                                                        if (columnName == null || "*".equals(getColumnName(columnName))) {
15697                                                                                                continue;
15698                                                                                        }
15699                                                                                        resultColumn.bindStarLinkColumn(columnName);
15700                                                                                }
15701                                                                        }
15702                                                                } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
15703                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
15704                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
15705                                                                                for (ResultColumn item : tableModel.getColumns()) {
15706                                                                                        if (item.hasStarLinkColumn()) {
15707                                                                                                for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
15708                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
15709                                                                                                }
15710                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
15711                                                                                                resultColumn.bindStarLinkColumn((TObjectName) item.getColumnObject());
15712                                                                                        } else if (item.getColumnObject() instanceof TResultColumn) {
15713                                                                                                TResultColumn queryTableColumn = (TResultColumn) item.getColumnObject();
15714                                                                                                TObjectName tableColumnObject = queryTableColumn.getFieldAttr();
15715                                                                                                if (tableColumnObject != null) {
15716                                                                                                        resultColumn.bindStarLinkColumn(tableColumnObject);
15717                                                                                                } else if (queryTableColumn.getAliasClause() != null) {
15718                                                                                                        resultColumn.bindStarLinkColumn(
15719                                                                                                                        queryTableColumn.getAliasClause().getAliasName());
15720                                                                                                }
15721                                                                                        }
15722                                                                                }
15723                                                                        }
15724                                                                }
15725                                                        } else {
15726                                                                ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
15727                                                                TTableList tables = stmt.getTables();
15728                                                                for (int k = 0; k < tables.size(); k++) {
15729                                                                        TTable table = tables.getTable(k);
15730                                                                        TObjectName[] columns = modelManager.getTableColumns(table);
15731                                                                        for (int j = 0; j < columns.length; j++) {
15732                                                                                TObjectName columnName = columns[j];
15733                                                                                if (columnName == null) {
15734                                                                                        continue;
15735                                                                                }
15736                                                                                if ("*".equals(getColumnName(columnName))) {
15737                                                                                        if (modelManager.getModel(table) instanceof Table) {
15738                                                                                                Table tableModel = (Table) modelManager.getModel(table);
15739                                                                                                if (tableModel != null) {
15740                                                                                                        modelFactory.createTableColumn(tableModel, columnName, false);
15741                                                                                                }
15742                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
15743                                                                                                        for (int z = 0; z < tableModel.getColumns().size(); z++) {
15744                                                                                                                resultColumn.bindStarLinkColumn(
15745                                                                                                                                tableModel.getColumns().get(z).getColumnObject());
15746                                                                                                        }
15747                                                                                                }
15748                                                                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
15749                                                                                                QueryTable tableModel = (QueryTable) modelManager.getModel(table);
15750                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
15751                                                                                                        for (ResultColumn item : tableModel.getColumns()) {
15752                                                                                                                if (item.hasStarLinkColumn()) {
15753                                                                                                                        for (TObjectName starLinkColumn : item
15754                                                                                                                                        .getStarLinkColumnList()) {
15755                                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
15756                                                                                                                        }
15757                                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
15758                                                                                                                        resultColumn.bindStarLinkColumn(
15759                                                                                                                                        (TObjectName) item.getColumnObject());
15760                                                                                                                } else if (item.getColumnObject() instanceof TResultColumn) {
15761                                                                                                                        TResultColumn queryTableColumn = (TResultColumn) item
15762                                                                                                                                        .getColumnObject();
15763                                                                                                                        TObjectName tableColumnObject = queryTableColumn
15764                                                                                                                                        .getFieldAttr();
15765                                                                                                                        if (tableColumnObject != null) {
15766                                                                                                                                resultColumn.bindStarLinkColumn(tableColumnObject);
15767                                                                                                                        } else if (queryTableColumn.getAliasClause() != null) {
15768                                                                                                                                resultColumn.bindStarLinkColumn(queryTableColumn
15769                                                                                                                                                .getAliasClause().getAliasName());
15770                                                                                                                        }
15771                                                                                                                }
15772                                                                                                        }
15773                                                                                                }
15774                                                                                        }
15775                                                                                        continue;
15776                                                                                }
15777                                                                                resultColumn.bindStarLinkColumn(columnName);
15778                                                                        }
15779                                                                }
15780                                                        }
15781                                                }
15782                                                else {
15783                                                        ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
15784                                                }
15785                                                
15786                                                analyzeResultColumn(column, EffectType.select);
15787
15788                                        }
15789                                        
15790                                        if (queryModel instanceof ResultSet) {
15791                                                boolean isDetermined = true;
15792                                                ResultSet resultSet = (ResultSet) queryModel;
15793                                                for (ResultColumn column : resultSet.getColumns()) {
15794                                                        if (column.getName().endsWith("*")) {
15795                                                                isDetermined = false;
15796                                                                break;
15797                                                        }
15798                                                }
15799                                                if (isDetermined) {
15800                                                        resultSet.setDetermined(isDetermined);
15801                                                }
15802                                        }
15803                                }
15804                        }
15805
15806                
15807                        analyzeSelectIntoClause(stmt);
15808                
15809
15810                        if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
15811                                for (int i = 0; i < stmt.getJoins().size(); i++) {
15812                                        TJoin join = stmt.getJoins().getJoin(i);
15813                                        ResultSet topResultSet = (ResultSet) modelManager.getModel(stmt);
15814                                        if (join.getJoinItems() != null && join.getJoinItems().size() > 0) {
15815                                                for (int k = 0; k < join.getJoinItems().size(); k++) {
15816                                                        TTable table = join.getJoinItems().getJoinItem(k).getTable();
15817                                                        if (table != null && table.getSubquery() != null) {
15818                                                                
15819                                                                ResultSet joinResultSet = (ResultSet) modelManager.getModel(table.getSubquery());
15820                                                                for (int x = 0; x < joinResultSet.getColumns().size(); x++) {
15821                                                                        ResultColumn sourceColumn = joinResultSet.getColumns().get(x);
15822                                                                        ResultColumn resultColumn = matchResultColumn(topResultSet.getColumns(),
15823                                                                                        sourceColumn);
15824                                                                        if (resultColumn != null
15825                                                                                        && resultColumn.getColumnObject() instanceof TResultColumn) {
15826                                                                                TResultColumn column = (TResultColumn) resultColumn.getColumnObject();
15827                                                                                if (column.getAliasClause() == null && column.getFieldAttr() != null) {
15828                                                                                        TObjectName resultObject = column.getFieldAttr();
15829                                                                                        if (resultObject.getSourceTable() == null
15830                                                                                                        || resultObject.getSourceTable().equals(table)) {
15831                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
15832                                                                                                                .createDataFlowRelation();
15833                                                                                                combinedQueryRelation.setEffectType(EffectType.select);
15834                                                                                                combinedQueryRelation
15835                                                                                                                .setTarget(new ResultColumnRelationshipElement(resultColumn));
15836                                                                                                combinedQueryRelation
15837                                                                                                                .addSource(new ResultColumnRelationshipElement(sourceColumn));
15838                                                                                        }
15839                                                                                }
15840                                                                        }
15841                                                                }
15842                                                        }
15843                                                        
15844                                                        if(join.getJoinItems().getJoinItem(k).getJoin()!=null) {
15845                                                                analyzeJoin(join.getJoinItems().getJoinItem(k).getJoin(), EffectType.select);
15846                                                        }
15847                                                }
15848                                        }
15849                                        analyzeJoin(join, EffectType.select);
15850                                }
15851                        }
15852
15853                        if (stmt.getWhereClause() != null) {
15854                                TExpression expr = stmt.getWhereClause().getCondition();
15855                                if (expr != null) {
15856                                        analyzeFilterCondition(null, expr, null, JoinClauseType.where, EffectType.select);
15857                                }
15858                        }
15859
15860                        stmtStack.pop();
15861                }
15862        }
15863
15864        protected boolean isTopResultSet(TSelectSqlStatement stmt) {
15865                TCustomSqlStatement parent = stmt.getParentStmt();
15866                if (parent == null)
15867                        return true;
15868                if (parent instanceof TMssqlReturn) {
15869                        return true;
15870                }
15871                if (parent instanceof TReturnStmt) {
15872                        return true;
15873                }
15874                if (parent instanceof TCommonBlock) {
15875                        TCommonBlock block = (TCommonBlock) parent;
15876                        if (block.getStatements() != null) {
15877                                for (int i = 0; i < block.getStatements().size(); i++) {
15878                                        TCustomSqlStatement child = block.getStatements().get(i);
15879                                        if(stmt == child) {
15880                                                return true;
15881                                        }
15882                                }
15883                        }
15884                }
15885                if (parent instanceof TMssqlBlock) {
15886                        TMssqlBlock block = (TMssqlBlock) parent;
15887                        if (block.getStatements() != null) {
15888                                for (int i = 0; i < block.getStatements().size(); i++) {
15889                                        TCustomSqlStatement child = block.getStatements().get(i);
15890                                        if(stmt == child) {
15891                                                return true;
15892                                        }
15893                                }
15894                        }
15895                }
15896                if (parent instanceof TStoredProcedureSqlStatement) {
15897                        TStoredProcedureSqlStatement block = (TStoredProcedureSqlStatement) parent;
15898                        if (block.getStatements() != null) {
15899                                for (int i = 0; i < block.getStatements().size(); i++) {
15900                                        TCustomSqlStatement child = block.getStatements().get(i);
15901                                        if(child == stmt) {
15902                                                return true;
15903                                        }
15904                                        if (child instanceof TReturnStmt) {
15905                                                TReturnStmt returnStmt = (TReturnStmt) child;
15906                                                if (returnStmt.getStatements() != null) {
15907                                                        for (int j = 0; j < returnStmt.getStatements().size(); j++) {
15908                                                                TCustomSqlStatement child1 = returnStmt.getStatements().get(j);
15909                                                                if(child1 == stmt) {
15910                                                                        return true;
15911                                                                }
15912                                                        }
15913                                                }
15914                                        }
15915                                        if (child instanceof TMssqlReturn) {
15916                                                TMssqlReturn returnStmt = (TMssqlReturn) child;
15917                                                if (returnStmt.getStatements() != null) {
15918                                                        for (int j = 0; j < returnStmt.getStatements().size(); j++) {
15919                                                                TCustomSqlStatement child1 = returnStmt.getStatements().get(j);
15920                                                                if(child1 == stmt) {
15921                                                                        return true;
15922                                                                }
15923                                                        }
15924                                                }
15925                                        }
15926                                }
15927                        }
15928                }
15929                return false;
15930        }
15931
15932        protected void analyzeTableSubquery(TTable table) {
15933                if(table.getSubquery()!=null) {
15934                        QueryTable queryTable = modelFactory.createQueryTable(table);
15935                        TSelectSqlStatement subquery = table.getSubquery();
15936                        analyzeSelectStmt(subquery);
15937
15938                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
15939
15940                        if (resultSetModel != null && resultSetModel != queryTable
15941                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15942                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15943                                impactRelation.setEffectType(EffectType.select);
15944                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15945                                                resultSetModel.getRelationRows()));
15946                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15947                                                queryTable.getRelationRows()));
15948                        }
15949
15950                        if (resultSetModel != null && resultSetModel != queryTable
15951                                        && queryTable.getTableObject().getAliasClause() != null
15952                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
15953                                for (int j = 0; j < queryTable.getColumns().size()
15954                                                && j < resultSetModel.getColumns().size(); j++) {
15955                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15956                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
15957
15958                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
15959                                        queryRalation.setEffectType(EffectType.select);
15960                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15961                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15962                                }
15963                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
15964                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
15965                                                .getModel(subquery);
15966                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
15967                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
15968                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
15969                                                        sourceColumn);
15970                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15971                                                targetColumn.bindStarLinkColumn(starLinkColumn);
15972                                        }
15973                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15974                                        selectSetRalation.setEffectType(EffectType.select);
15975                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15976                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15977                                }
15978                        }
15979                }
15980        }
15981
15982        private ResultColumn getPivotedTableColumn(TPivotedTable pivotedTable, TObjectName columnName) {
15983                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
15984                if (pivotedTable.getPivotClause() != null) {
15985                        pivotClauses.add(pivotedTable.getPivotClause());
15986                }
15987                if (pivotedTable.getPivotClauseList() != null) {
15988                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
15989                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
15990                        }
15991                }
15992                for (TPivotClause clause : pivotClauses) {
15993                        Object model = modelManager.getModel(clause);
15994                        if (model instanceof PivotedTable) {
15995                                PivotedTable pivotedTableModel = (PivotedTable) model;
15996                                if (pivotedTableModel.getColumns() != null) {
15997                                        for (ResultColumn column : pivotedTableModel.getColumns()) {
15998                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
15999                                                                getColumnName(SQLUtil.trimColumnStringQuote(column.getName())))) {
16000                                                        return column;
16001                                                }
16002                                        }
16003                                }
16004                        }
16005                }
16006                return null;
16007        }
16008
16009        private void analyzeHiveTransformClause(TSelectSqlStatement stmt, THiveTransformClause transformClause) {
16010                Table mapSourceTable = null;
16011                QueryTable mapQueryTable = null;
16012                if(stmt.getTables()!=null) {
16013                        for(int i=0;i<stmt.getTables().size();i++) {
16014                                TTable table = stmt.getTables().getTable(i);
16015                                if (table.getSubquery() != null) {
16016                                        if (transformClause.getTransformType() == ETransformType.ettReduce) {
16017                                                mapQueryTable = modelFactory.createQueryTable(table);
16018                                        }
16019                                        analyzeSelectStmt(table.getSubquery());
16020                                }
16021                                else {
16022                                        mapSourceTable = modelFactory.createTable(table);
16023                                }
16024                        }
16025                }
16026                
16027                if (transformClause.getTransformType() == ETransformType.ettReduce) {
16028                        modelFactory.createResultSet(stmt, false);
16029                }
16030                
16031                List<TableColumn> mapTableColumns = new ArrayList<TableColumn>();
16032                List<ResultColumn> mapResultSetColumns = new ArrayList<ResultColumn>();
16033                List<ResultColumn> redueResultSetColumns = new ArrayList<ResultColumn>();
16034                
16035                if(transformClause.getExpressionList()!=null) {
16036                        for(TExpression expression: transformClause.getExpressionList()) {
16037                                if(expression.getObjectOperand()!=null) {
16038                                        if (transformClause.getTransformType() == ETransformType.ettMap || transformClause.getTransformType() == ETransformType.ettSelect) {
16039                                                if (mapSourceTable != null) {
16040                                                        TableColumn tableColumn = modelFactory.createTableColumn(mapSourceTable,
16041                                                                        expression.getObjectOperand(), false);
16042                                                        if (tableColumn != null) {
16043                                                                mapTableColumns.add(tableColumn);
16044                                                        }
16045                                                }
16046                                        }
16047                                        else if (transformClause.getTransformType() == ETransformType.ettReduce) {
16048                                                if (mapQueryTable != null) {
16049                                                        ResultColumn resultColumn = modelFactory.createResultColumn(mapQueryTable,
16050                                                                        expression.getObjectOperand(), false);
16051                                                        if (resultColumn != null) {
16052                                                                mapResultSetColumns.add(resultColumn);
16053                                                        }
16054                                                }
16055                                        }
16056                                }
16057                        }
16058                }
16059                
16060                if (transformClause.getAliasClause() != null) {
16061                        Object model = modelManager.getModel(stmt);
16062                        if (model instanceof ResultSet) {
16063                                ResultSet result = (ResultSet) model;
16064                                if (result!=null && transformClause.getAliasClause().getColumns() != null) {
16065                                        for (TObjectName column : transformClause.getAliasClause().getColumns()) {
16066                                                ResultColumn resultColumn = modelFactory.createResultColumn(result, column);
16067                                                if (resultColumn != null) {
16068                                                        if (transformClause.getTransformType() == ETransformType.ettMap 
16069                                                                        || transformClause.getTransformType() == ETransformType.ettSelect) {
16070                                                                mapResultSetColumns.add(resultColumn);
16071                                                        }
16072                                                        else if (transformClause.getTransformType() == ETransformType.ettReduce) {
16073                                                                redueResultSetColumns.add(resultColumn);
16074                                                        }
16075                                                }
16076                                        }
16077                                }
16078                        }
16079                }
16080                
16081                if (transformClause.getTransformType() == ETransformType.ettMap 
16082                                || transformClause.getTransformType() == ETransformType.ettSelect) {
16083                        if (!mapTableColumns.isEmpty() && !mapResultSetColumns.isEmpty()) {
16084                                for (ResultColumn resultColumn : mapResultSetColumns) {
16085                                        for (TableColumn tableColumn : mapTableColumns) {
16086                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16087                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16088                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16089                                                relation.setEffectType(EffectType.select);
16090                                        }
16091                                }
16092                        }
16093                }
16094                else if (transformClause.getTransformType() == ETransformType.ettReduce) {
16095                        if (!redueResultSetColumns.isEmpty() && !mapResultSetColumns.isEmpty()) {
16096                                for (ResultColumn reduceResultColumn : redueResultSetColumns) {
16097                                        for (ResultColumn mapResultColumn : mapResultSetColumns) {
16098                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16099                                                relation.setTarget(new ResultColumnRelationshipElement(reduceResultColumn));
16100                                                relation.addSource(new ResultColumnRelationshipElement(mapResultColumn));
16101                                                relation.setEffectType(EffectType.select);
16102                                        }
16103                                }
16104                        }
16105                }
16106        }
16107
16108        protected boolean isStructColumn(TObjectName columnName) {
16109                return columnName.getSourceTable() != null && columnName.getSourceTable().getAliasClause() != null
16110                                && columnName.getSourceTable().getUnnestClause() != null
16111                                && DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
16112                                                getColumnName(columnName.getSourceTable().getAliasClause().getAliasName()));
16113        }
16114
16115        private TObjectName getObjectName(ResultColumn column) {
16116                if (column.getColumnObject() instanceof TResultColumn) {
16117                        TResultColumn resultColumn = (TResultColumn) column.getColumnObject();
16118                        if (resultColumn.getAliasClause() != null && resultColumn.getAliasClause().getAliasName() != null) {
16119                                return resultColumn.getAliasClause().getAliasName();
16120                        }
16121                        if (resultColumn.getFieldAttr() != null) {
16122                                return resultColumn.getFieldAttr();
16123                        }
16124                        if (resultColumn.getExpr() != null
16125                                        && resultColumn.getExpr().getExpressionType() == EExpressionType.simple_object_name_t) {
16126                                return resultColumn.getExpr().getObjectOperand();
16127                        }
16128                } else if (column.getColumnObject() instanceof TObjectName) {
16129                        return (TObjectName) column.getColumnObject();
16130                }
16131                return null;
16132        }
16133
16134        private boolean isShowTopSelectResultSet() {
16135                if (option.isSimpleOutput() && !option.isSimpleShowTopSelectResultSet())
16136                        return false;
16137                return true;
16138        }
16139
16140        private void analyzeSelectIntoClause(TSelectSqlStatement stmt) {
16141                if (stmt.getParentStmt() instanceof TSelectSqlStatement) {
16142                        return;
16143                }
16144                
16145                TableColumn oracleIntoTableColumn = null;
16146                
16147                TIntoClause intoClause = stmt.getIntoClause();
16148                if (intoClause == null && stmt.getLeftStmt() != null) {
16149                        intoClause = stmt.getLeftStmt().getIntoClause();
16150                }
16151                
16152                if (intoClause != null) {
16153                        List<TObjectName> tableNames = new ArrayList<TObjectName>();
16154                        if (intoClause.getExprList() != null) {
16155                                for (int j = 0; j < intoClause.getExprList().size(); j++) {
16156                                        TObjectName tableName = intoClause.getExprList().getExpression(j).getObjectOperand();
16157                                        if (tableName != null) {
16158                                                if (tableName.toString().startsWith(":") && option.getVendor() == EDbVendor.dbvoracle
16159                                                                && tableName.getDbObjectType() == EDbObjectType.column) {
16160                                                        TObjectName tableAlias = new TObjectName();
16161                                                        tableAlias.setString(tableName.getTableString());
16162                                                        tableNames.add(tableAlias);
16163                                                        TTable sourceTable = tableName.getSourceTable();
16164                                                        Table sourceTableModel = modelFactory.createTable(sourceTable, tableAlias);
16165                                                        oracleIntoTableColumn = modelFactory.createTableColumn(sourceTableModel, tableName, true);
16166                                                } else {
16167                                                        if (tableName != null) {
16168                                                                tableNames.add(tableName);
16169                                                        }
16170                                                }
16171                                        }
16172                                        else if(intoClause.getExprList().getExpression(j).getFunctionCall()!=null) {
16173                                                TObjectName variableName = intoClause.getExprList().getExpression(j).getFunctionCall().getFunctionName();
16174                                                tableNames.add(variableName);
16175                                                Variable variable = modelFactory.createVariable(variableName);
16176                                                variable.setSubType(SubType.record);
16177                                                TObjectName variableProperties = new TObjectName();
16178                                                variableProperties.setString("*");
16179                                                modelFactory.createTableColumn(variable, variableProperties, true);
16180                                        }
16181                                }
16182                        } else if (intoClause.getVariableList() != null) {
16183                                for (int j = 0; j < intoClause.getVariableList().size(); j++) {
16184                                        TObjectName tableName = intoClause.getVariableList().getObjectName(j);
16185                                        if (tableName != null) {
16186                                                tableNames.add(tableName);
16187                                        }
16188                                }
16189                        } else if (intoClause.getIntoName() != null) {
16190                                tableNames.add(intoClause.getIntoName());
16191                        }
16192
16193                        ResultSet queryModel = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
16194                        if (stmt.getSetOperatorType() != ESetOperatorType.none) {
16195                                queryModel = (ResultSet) modelManager.getModel(stmt);
16196                        }
16197                        for (int j = 0; j < tableNames.size(); j++) {
16198                                TObjectName tableName = tableNames.get(j);
16199                                if (tableName.getColumnNameOnly().startsWith("@")
16200                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
16201                                        continue;
16202                                }
16203
16204                                if (tableName.getColumnNameOnly().startsWith(":")
16205                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
16206                                        continue;
16207                                }
16208
16209                                Table tableModel;
16210                                TableColumn variableColumn = null;
16211
16212                                if (tableName.getDbObjectType() == EDbObjectType.variable) {
16213                                        if (tableName.toString().indexOf(".") != -1) {
16214                                                List<String> splits = SQLUtil.parseNames(tableName.toString());
16215                                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
16216                                        } else {
16217                                                tableModel = modelFactory.createVariable(tableName);
16218                                        }
16219                                        if (tableModel.getSubType() == null) {
16220                                                tableModel.setSubType(SubType.record);
16221                                        }
16222                                        if(tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
16223                                                TObjectName variableProperties = new TObjectName();
16224                                                variableProperties.setString("*");
16225                                                variableColumn = modelFactory.createTableColumn(tableModel, variableProperties, true);
16226                                        }
16227                                } else {
16228                                        tableModel = modelFactory.createTableByName(tableName);
16229                                }
16230                                
16231                                if (queryModel instanceof ResultSet && (stmt.getWhereClause() != null || hasJoin(stmt))) {
16232                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
16233                                        impactRelation.setEffectType(EffectType.insert);
16234                                        impactRelation.addSource(
16235                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)queryModel).getRelationRows()));
16236                                        impactRelation.setTarget(
16237                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
16238                                }
16239                                
16240                                Process process = modelFactory.createProcess(stmt);
16241                                tableModel.addProcess(process);
16242                                
16243                                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
16244                                        for (ResultColumn resultColumn : queryModel.getColumns()) {
16245                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
16246                                                                resultColumn.getName());
16247
16248                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
16249                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
16250                                                        TSQLSchema schema = sqlenv
16251                                                                        .getSQLSchema(tableModel.getDatabase() + "." + tableModel.getSchema(), true);
16252                                                        if (schema != null) {
16253                                                                TSQLTable tempTable = schema
16254                                                                                .createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
16255                                                                tempTable.addColumn(tableColumn.getName());
16256                                                        }
16257                                                }
16258
16259                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16260                                                relation.setEffectType(EffectType.insert);
16261                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16262                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16263                                                relation.setProcess(process);
16264                                        }
16265                                        
16266                                        tableModel.setDetermined(queryModel.isDetermined());
16267                                        if(queryModel.isDetermined() && DlineageUtil.isTempTable(tableModel, option.getVendor())) {
16268                                                tableModel.setCreateTable(true, false);
16269                                        }
16270                                        return;
16271                                }
16272
16273                                boolean isDetermined = true;
16274                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
16275                                        if (tableNames.size() > 1 && tableName.getDbObjectType() == EDbObjectType.variable) {
16276                                                if (i != j) {
16277                                                        continue;
16278                                                }
16279                                        }
16280                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
16281
16282                                        if ("*".equals(column.getColumnNameOnly()) && column.getFieldAttr() != null
16283                                                        && column.getFieldAttr().getSourceTable() != null) {
16284                                                Object model = modelManager.getModel(column);
16285                                                if(model instanceof LinkedHashMap) {
16286                                                        LinkedHashMap<String, ResultColumn> columns = (LinkedHashMap<String, ResultColumn>)model;
16287                                                        for(String key: columns.keySet()) {
16288                                                                ResultColumn sourceColumn = columns.get(key);
16289                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
16290                                                                                sourceColumn.getName());
16291                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16292                                                                relation.setEffectType(EffectType.insert);
16293                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16294                                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
16295                                                                relation.setProcess(process);
16296                                                        }
16297                                                }
16298                                                else if(model instanceof ResultColumn) {
16299                                                        isDetermined = false;
16300                                                        ResultColumn resultColumn = (ResultColumn) model;
16301                                                        List<TObjectName> columns = resultColumn.getStarLinkColumnList();
16302                                                        if (columns.size() > 0) {
16303                                                                for (int k = 0; k < columns.size(); k++) {
16304        
16305                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
16306                                                                                        columns.get(k));
16307        
16308                                                                        if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
16309                                                                                        && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
16310                                                                                TSQLSchema schema = sqlenv.getSQLSchema(
16311                                                                                                tableModel.getDatabase() + "." + tableModel.getSchema(), true);
16312                                                                                if (schema != null) {
16313                                                                                        TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
16314                                                                                        tempTable.addColumn(tableColumn.getName());
16315                                                                                }
16316                                                                        }
16317        
16318                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16319                                                                        relation.setEffectType(EffectType.insert);
16320                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16321                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16322                                                                        relation.setProcess(process);
16323                                                                }
16324                                                                if (resultColumn.isShowStar()) {
16325                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
16326                                                                                        column.getFieldAttr());
16327                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16328                                                                        relation.setEffectType(EffectType.insert);
16329                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16330                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16331                                                                        relation.setProcess(process);
16332                                                                }
16333                                                        } else {
16334                                                                TObjectName columnObject = column.getFieldAttr();
16335                                                                if (column.getAliasClause() != null) {
16336                                                                        columnObject = column.getAliasClause().getAliasName();
16337                                                                }
16338                                                                if (columnObject != null) {
16339                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
16340                                                                                        columnObject);
16341                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16342                                                                        relation.setEffectType(EffectType.insert);
16343                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16344                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16345                                                                        relation.setProcess(process);
16346                                                                } else if (!SQLUtil.isEmpty(column.getColumnAlias())) {
16347                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
16348                                                                                        column.getAliasClause().getAliasName());
16349                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16350                                                                        relation.setEffectType(EffectType.insert);
16351                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16352                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16353                                                                        relation.setProcess(process);
16354                                                                }
16355                                                        }
16356                                                }
16357                                        } else {
16358                                                ResultColumn resultColumn = null;
16359
16360                                                if (queryModel instanceof QueryTable) {
16361                                                        resultColumn = (ResultColumn) modelManager.getModel(column);
16362                                                } else if (queryModel instanceof ResultSet) {
16363                                                        resultColumn = (ResultColumn) modelManager.getModel(column);
16364                                                } else {
16365                                                        continue;
16366                                                }
16367
16368                                                if (resultColumn == null && column.getAliasClause() != null) {
16369                                                        resultColumn = (ResultColumn) modelManager.getModel(column.getAliasClause().getAliasName());
16370                                                }
16371
16372                                                if (resultColumn != null) {
16373                                                        TObjectName columnObject = column.getFieldAttr();
16374                                                        if (column.getAliasClause() != null) {
16375                                                                columnObject = column.getAliasClause().getAliasName();
16376                                                        }
16377                                                        TableColumn tableColumn = null;
16378                                                        if (columnObject != null) {
16379                                                                if (tableModel.isVariable()) {
16380                                                                        if (variableColumn != null) {
16381                                                                                tableColumn = variableColumn;
16382                                                                        } else {
16383                                                                                tableColumn = tableModel.getColumns().get(0);
16384                                                                        }
16385                                                                } 
16386                                                                else if (oracleIntoTableColumn != null) {
16387                                                                        tableColumn = oracleIntoTableColumn;
16388                                                                }
16389                                                                else {
16390                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, columnObject);
16391                                                                        if (containStarColumn(queryModel)) {
16392                                                                                tableColumn.notBindStarLinkColumn(true);
16393                                                                        }
16394                                                                }
16395                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16396                                                                relation.setEffectType(EffectType.insert);
16397                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16398                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16399                                                                relation.setProcess(process);
16400                                                        } else if (!SQLUtil.isEmpty(column.getColumnAlias())) {
16401                                                                if (tableModel.isVariable()) {
16402                                                                        if (variableColumn != null) {
16403                                                                                tableColumn = variableColumn;
16404                                                                        } else {
16405                                                                                tableColumn = tableModel.getColumns().get(0);
16406                                                                        }
16407                                                                } else {
16408                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
16409                                                                                        column.getAliasClause().getAliasName());
16410                                                                }
16411                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16412                                                                relation.setEffectType(EffectType.insert);
16413                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16414                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16415                                                                relation.setProcess(process);
16416                                                        } else {
16417                                                                if (tableModel.isVariable()) {
16418                                                                        if (variableColumn != null) {
16419                                                                                tableColumn = variableColumn;
16420                                                                        } else {
16421                                                                                tableColumn = tableModel.getColumns().get(0);
16422                                                                        }
16423                                                                }
16424                                                                if (tableColumn != null) {
16425                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16426                                                                        relation.setEffectType(EffectType.insert);
16427                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
16428                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16429                                                                        relation.setProcess(process);
16430                                                                }
16431                                                        }
16432                                                }
16433                                        }
16434                                }
16435                                tableModel.setDetermined(isDetermined);
16436                                if(isDetermined && DlineageUtil.isTempTable(tableModel, option.getVendor())) {
16437                                        tableModel.setCreateTable(true, false);
16438                                }
16439                        }
16440                }
16441        }
16442
16443        private boolean isUnPivotedTable(TPivotedTable pivotedTable) {
16444                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
16445                        return pivotedTable.getPivotClauseList().getElement(0).getType() == TPivotClause.unpivot;
16446                } else {
16447                        TPivotClause pivotClause = pivotedTable.getPivotClause();
16448                        return pivotClause.getType() == TPivotClause.unpivot;
16449                }
16450        }
16451
16452        private void analyzeUnPivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) {
16453                List<Object> tables = new ArrayList<Object>();
16454                Set<Object> pivotedColumns = new HashSet<Object>();
16455                TTable fromTable = pivotedTable.getTableSource();
16456                Object table = modelManager.getModel(fromTable);
16457                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
16458                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
16459                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
16460                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
16461                        }
16462                } else {
16463                        TPivotClause pivotClause = pivotedTable.getPivotClause();
16464                        pivotClauses.add(pivotClause);
16465                }
16466
16467                for (int y = 0; y < pivotClauses.size(); y++) {
16468                        TPivotClause pivotClause = pivotClauses.get(y);
16469                        PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause);
16470                        pivotTable.setUnpivoted(true);
16471
16472                        if (pivotClause.getValueColumnList() != null) {
16473                                for (int j = 0; j < pivotClause.getValueColumnList().size(); j++) {
16474                                        modelFactory.createResultColumn(pivotTable, pivotClause.getValueColumnList().getObjectName(j));
16475                                }
16476                        }
16477                        if (pivotClause.getPivotColumnList() != null) {
16478                                for (int j = 0; j < pivotClause.getPivotColumnList().size(); j++) {
16479                                        modelFactory.createResultColumn(pivotTable, pivotClause.getPivotColumnList().getObjectName(j));
16480                                }
16481                        }
16482                        if (pivotClause.getUnpivotInClause().getItems() != null) {
16483                                for (int j = 0; j < pivotClause.getUnpivotInClause().getItems().size(); j++) {
16484                                        TObjectName columnName = pivotClause.getUnpivotInClause().getItems().getElement(j).getColumn();
16485                                        if (columnName != null) {
16486                                                if (table instanceof QueryTable) {
16487                                                        for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
16488                                                                if (getColumnName(columnName)
16489                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16490                                                                        for (ResultColumn resultColumn : pivotTable.getColumns()) {
16491                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16492                                                                                relation.setEffectType(EffectType.select);
16493                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16494                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16495                                                                                pivotedColumns.add(tableColumn);
16496                                                                        }
16497                                                                        break;
16498                                                                }
16499                                                        }
16500                                                } else if (table instanceof Table) {
16501                                                        for (TableColumn tableColumn : ((Table) table).getColumns()) {
16502                                                                if (getColumnName(columnName)
16503                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16504                                                                        for (ResultColumn resultColumn : pivotTable.getColumns()) {
16505                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16506                                                                                relation.setEffectType(EffectType.select);
16507                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16508                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16509                                                                                pivotedColumns.add(tableColumn);
16510                                                                        }
16511                                                                        break;
16512                                                                }
16513                                                        }
16514                                                }
16515                                        } else {
16516                                                TObjectNameList columnNames = pivotClause.getUnpivotInClause().getItems().getElement(j)
16517                                                                .getColumnList();
16518                                                for (TObjectName columnName1 : columnNames) {
16519                                                        if (table instanceof QueryTable) {
16520                                                                for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
16521                                                                        if (getColumnName(columnName1).equals(
16522                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16523                                                                                for (ResultColumn resultColumn : pivotTable.getColumns()) {
16524                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16525                                                                                        relation.setEffectType(EffectType.select);
16526                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16527                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16528                                                                                        pivotedColumns.add(tableColumn);
16529                                                                                }
16530                                                                                break;
16531                                                                        }
16532                                                                }
16533                                                        } else if (table instanceof Table) {
16534                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
16535                                                                        if (getColumnName(columnName1).equals(
16536                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16537                                                                                for (ResultColumn resultColumn : pivotTable.getColumns()) {
16538                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16539                                                                                        relation.setEffectType(EffectType.select);
16540                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16541                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
16542                                                                                        pivotedColumns.add(tableColumn);
16543                                                                                }
16544                                                                                break;
16545                                                                        }
16546                                                                }
16547                                                        }
16548                                                }
16549                                        }
16550                                }
16551                        }
16552                        tables.add(pivotTable);
16553                        tables.add(table);
16554                }
16555
16556                ResultSet resultSet = modelFactory.createResultSet(stmt,
16557                                isTopResultSet(stmt) && isShowTopSelectResultSet());
16558                TResultColumnList columnList = stmt.getResultColumnList();
16559                for (int i = 0; i < columnList.size(); i++) {
16560                        TResultColumn column = columnList.getResultColumn(i);
16561                        ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
16562                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
16563                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
16564                                if (columnObject.getFieldAttr() != null) {
16565                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
16566                                                resultColumn.setShowStar(false);
16567                                                int index = 0;
16568                                                for (int k = 0; k < tables.size(); k++) {
16569                                                        Object tableItem = tables.get(k);
16570                                                        if (tableItem instanceof ResultSet) {
16571                                                                for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) {
16572                                                                        ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
16573                                                                        if (pivotedColumns.contains(tableColumn)) {
16574                                                                                continue;
16575                                                                        }
16576                                                                        if (tableColumn.getColumnObject() instanceof TObjectName) {
16577                                                                                resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject());
16578                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16579                                                                                relation.setEffectType(EffectType.select);
16580                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
16581                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16582                                                                        } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
16583                                                                                if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
16584                                                                                        if (tableColumn.hasStarLinkColumn()) {
16585                                                                                                for (int z = 0; z < tableColumn.getStarLinkColumnList().size(); z++) {
16586                                                                                                        ResultColumn resultColumn1 = modelFactory.createResultColumn(
16587                                                                                                                        (ResultSet) tableItem,
16588                                                                                                                        tableColumn.getStarLinkColumnList().get(z));
16589                                                                                                        DataFlowRelationship relation = modelFactory
16590                                                                                                                        .createDataFlowRelation();
16591                                                                                                        relation.setEffectType(EffectType.select);
16592                                                                                                        relation.setTarget(
16593                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
16594                                                                                                        relation.addSource(
16595                                                                                                                        new ResultColumnRelationshipElement(resultColumn1));
16596                                                                                                        tableColumn.getStarLinkColumns().remove(
16597                                                                                                                        getColumnName(tableColumn.getStarLinkColumnList().get(z)));
16598                                                                                                        z--;
16599                                                                                                }
16600                                                                                        } else {
16601                                                                                                resultColumn.bindStarLinkColumn(
16602                                                                                                                ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr());
16603                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16604                                                                                                relation.setEffectType(EffectType.select);
16605                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr()));
16606                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16607                                                                                        }
16608                                                                                } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) {
16609                                                                                        TExpression expr = ((TResultColumn) tableColumn.getColumnObject())
16610                                                                                                        .getExpr();
16611                                                                                        if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
16612                                                                                                TObjectName columnName = new TObjectName();
16613                                                                                                columnName.setString(expr.toString());
16614                                                                                                resultColumn.bindStarLinkColumn(columnName);
16615                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16616                                                                                                relation.setEffectType(EffectType.select);
16617                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, columnName));
16618                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16619                                                                                        }
16620                                                                                }
16621                                                                        }
16622                                                                }
16623                                                        } else if (tableItem instanceof Table) {
16624                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
16625                                                                        if (pivotedColumns.contains(tableColumn)) {
16626                                                                                continue;
16627                                                                        }
16628                                                                        resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(), index);
16629                                                                        index++;
16630                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16631                                                                        relation.setEffectType(EffectType.select);
16632                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
16633                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
16634                                                                }
16635                                                        }
16636                                                }
16637                                        } else {
16638                                                for (int k = 0; k < tables.size(); k++) {
16639                                                        Object tableItem = tables.get(k);
16640                                                        if (tableItem instanceof ResultSet) {
16641                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
16642                                                                        if (getColumnName(columnObject.getFieldAttr()).equals(
16643                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16644                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16645                                                                                relation.setEffectType(EffectType.select);
16646                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16647                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16648                                                                                break;
16649                                                                        }
16650                                                                }
16651                                                        } else if (tableItem instanceof Table) {
16652                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
16653                                                                        if (getColumnName(columnObject.getFieldAttr()).equals(
16654                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16655                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16656                                                                                relation.setEffectType(EffectType.select);
16657                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16658                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16659                                                                                break;
16660                                                                        }
16661                                                                }
16662                                                        }
16663                                                }
16664                                        }
16665                                } else if (columnObject.getExpr() != null) {
16666                                        analyzeResultColumn(column, EffectType.select);
16667                                }
16668                        }
16669                }
16670        }
16671
16672        private void analyzePivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) {
16673                List<Object> tables = new ArrayList<Object>();
16674                Set<Object> pivotedColumns = new HashSet<Object>();
16675                TTable fromTable = pivotedTable.getTableSource();
16676                Object table = modelManager.getModel(fromTable);
16677                if(table == null && fromTable.getSubquery()!=null) {
16678                        table = modelFactory.createQueryTable(fromTable);
16679                        TSelectSqlStatement subquery = fromTable.getSubquery();
16680                        analyzeSelectStmt(subquery);
16681                }
16682                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
16683                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
16684                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
16685                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
16686                        }
16687                } else {
16688                        TPivotClause pivotClause = pivotedTable.getPivotClause();
16689                        pivotClauses.add(pivotClause);
16690                }
16691
16692                for (int y = 0; y < pivotClauses.size(); y++) {
16693                        TPivotClause pivotClause = pivotClauses.get(y);
16694                        List<TFunctionCall> functionCalls = new ArrayList<TFunctionCall>();
16695                        if (pivotClause.getAggregation_function() != null || pivotClause.getAggregation_function_list() != null) {
16696                                if (pivotClause.getAggregation_function() != null) {
16697                                        functionCalls.add((TFunctionCall) pivotClause.getAggregation_function());
16698                                } else if (pivotClause.getAggregation_function_list() != null) {
16699                                        for (int i = 0; i < pivotClause.getAggregation_function_list().size(); i++) {
16700                                                functionCalls.add((TFunctionCall) pivotClause.getAggregation_function_list().getResultColumn(i)
16701                                                                .getExpr().getFunctionCall());
16702                                        }
16703                                }
16704
16705                                if (functionCalls.isEmpty()) {
16706                                        return;
16707                                }
16708
16709                                if (pivotClause.getPivotColumnList() == null) {
16710                                        return;
16711                                }
16712
16713                                if (pivotClause.getPivotInClause() == null) {
16714                                        return;
16715                                }
16716
16717                                for (int x = 0; x < functionCalls.size(); x++) {
16718                                        TFunctionCall functionCall = functionCalls.get(x);
16719                                        Function function = modelFactory.createFunction(functionCall);
16720                                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
16721                                                        ((TFunctionCall) functionCall).getFunctionName());
16722
16723                                        List<TExpression> expressions = new ArrayList<TExpression>();
16724                                        getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall);
16725
16726                                        for (int j = 0; j < expressions.size(); j++) {
16727                                                columnsInExpr visitor = new columnsInExpr();
16728                                                expressions.get(j).inOrderTraverse(visitor);
16729                                                List<TObjectName> objectNames = visitor.getObjectNames();
16730                                                if (objectNames == null) {
16731                                                        continue;
16732                                                }
16733                                                for (TObjectName columnName : objectNames) {
16734                                                        if (table instanceof QueryTable) {
16735                                                                for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) {
16736                                                                        boolean find = false;
16737                                                                        ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i);
16738                                                                        if (tableColumn.hasStarLinkColumn()) {
16739                                                                                for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) {
16740                                                                                        TObjectName objectName = tableColumn.getStarLinkColumnList().get(k);
16741                                                                                        if (getColumnName(columnName).equals(getColumnName(objectName))) {
16742                                                                                                ResultColumn resultColumn = modelFactory
16743                                                                                                                .createResultColumn((QueryTable) table, objectName);
16744                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16745                                                                                                relation.setEffectType(EffectType.select);
16746                                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
16747                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16748                                                                                                pivotedColumns.add(resultColumn);
16749                                                                                                tableColumn.getStarLinkColumns()
16750                                                                                                                .remove(DlineageUtil.getColumnName(objectName));
16751                                                                                                find = true;
16752                                                                                                break;
16753                                                                                        }
16754                                                                                }
16755                                                                        } else if (getColumnName(columnName).equals(
16756                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16757                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16758                                                                                relation.setEffectType(EffectType.select);
16759                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
16760                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16761                                                                                pivotedColumns.add(tableColumn);
16762                                                                                find = true;
16763                                                                                break;
16764                                                                        } 
16765                                                                        
16766                                                                        if (!find && tableColumn.getName().endsWith("*")) {
16767                                                                                QueryTable queryTable = (QueryTable)table;
16768                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(queryTable, columnName);
16769                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16770                                                                                relation.setEffectType(EffectType.select);
16771                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
16772                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
16773                                                                                tableColumn.bindStarLinkColumn(columnName);
16774                                                                        }
16775                                                                }
16776                                                        } else if (table instanceof Table) {
16777                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
16778                                                                        if (getColumnName(columnName).equals(
16779                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
16780                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16781                                                                                relation.setEffectType(EffectType.select);
16782                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
16783                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16784                                                                                pivotedColumns.add(tableColumn);
16785                                                                                break;
16786                                                                        }
16787                                                                }
16788                                                        }
16789                                                }
16790                                        }
16791
16792                                        PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause);
16793                                        pivotTable.setUnpivoted(false);
16794
16795                                        if (pivotClause.getPivotInClause().getItems() != null) {
16796                                                for (int j = 0; j < pivotClause.getPivotInClause().getItems().size(); j++) {
16797                                                        ResultColumn resultColumn = null;
16798                                                        if (pivotClause.getAggregation_function_list() != null
16799                                                                        && pivotClause.getAggregation_function_list().size() > 1) {
16800                                                                TResultColumn functionColumn = pivotClause.getAggregation_function_list()
16801                                                                                .getResultColumn(x);
16802                                                                TObjectName tableColumn = new TObjectName();
16803                                                                if (option.getVendor() == EDbVendor.dbvbigquery) {
16804                                                                        tableColumn.setString(getResultColumnString(functionColumn) + "_"
16805                                                                                        + SQLUtil.trimColumnStringQuote(getResultColumnString(
16806                                                                                                        pivotClause.getPivotInClause().getItems().getResultColumn(j))));
16807                                                                }
16808                                                                else {
16809                                                                        tableColumn.setString(SQLUtil
16810                                                                                        .trimColumnStringQuote(getResultColumnString(
16811                                                                                                        pivotClause.getPivotInClause().getItems().getResultColumn(j)))
16812                                                                                        + "_" + getResultColumnString(functionColumn));
16813                                                                }
16814                                                                resultColumn = modelFactory.createResultColumn(pivotTable, tableColumn);
16815                                                        } else {
16816                                                                resultColumn = modelFactory.createSelectSetResultColumn(pivotTable,
16817                                                                                pivotClause.getPivotInClause().getItems().getResultColumn(j), j);
16818                                                        }
16819                                                        {
16820                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16821                                                                relation.setEffectType(EffectType.select);
16822                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16823                                                                relation.addSource(new ResultColumnRelationshipElement(column));
16824                                                        }
16825                                                        {
16826                                                                for (TObjectName columnName : pivotClause.getPivotColumnList()) {
16827                                                                        if (table instanceof QueryTable) {
16828                                                                                for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) {
16829                                                                                        ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i);
16830                                                                                        if (tableColumn.hasStarLinkColumn()) {
16831                                                                                                for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) {
16832                                                                                                        TObjectName objectName = tableColumn.getStarLinkColumnList().get(k);
16833                                                                                                        if (getColumnName(columnName).equals(getColumnName(objectName))) {
16834                                                                                                                ResultColumn resultColumn1 = modelFactory
16835                                                                                                                                .createResultColumn((QueryTable) table, objectName);
16836                                                                                                                DataFlowRelationship relation = modelFactory
16837                                                                                                                                .createDataFlowRelation();
16838                                                                                                                relation.setEffectType(EffectType.select);
16839                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
16840                                                                                                                relation.addSource(
16841                                                                                                                                new ResultColumnRelationshipElement(resultColumn1));
16842                                                                                                                pivotedColumns.add(resultColumn1);
16843                                                                                                                tableColumn.getStarLinkColumns()
16844                                                                                                                                .remove(DlineageUtil.getColumnName(objectName));
16845                                                                                                                break;
16846                                                                                                        }
16847                                                                                                }
16848                                                                                        } else if (getColumnName(columnName).equals(DlineageUtil
16849                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
16850                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16851                                                                                                relation.setEffectType(EffectType.select);
16852                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16853                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16854                                                                                                pivotedColumns.add(tableColumn);
16855                                                                                                break;
16856                                                                                        }
16857                                                                                }
16858                                                                        } else if (table instanceof Table) {
16859                                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
16860                                                                                        if (getColumnName(columnName).equals(DlineageUtil
16861                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
16862                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16863                                                                                                relation.setEffectType(EffectType.select);
16864                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16865                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16866                                                                                                pivotedColumns.add(tableColumn);
16867                                                                                                break;
16868                                                                                        }
16869                                                                                }
16870                                                                        }
16871                                                                }
16872                                                        }
16873                                                }
16874                                        } else if (pivotClause.getPivotInClause().getSubQuery() != null) {
16875                                                TSelectSqlStatement subquery = pivotClause.getPivotInClause().getSubQuery();
16876                                                analyzeSelectStmt(subquery);
16877                                                ResultSet selectSetResultSetModel = (ResultSet) modelManager.getModel(subquery);
16878                                                for (int j = 0; j < subquery.getResultColumnList().size(); j++) {
16879                                                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(pivotTable,
16880                                                                        subquery.getResultColumnList().getResultColumn(j), j);
16881                                                        {
16882                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16883                                                                relation.setEffectType(EffectType.select);
16884                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16885                                                                relation.addSource(new ResultColumnRelationshipElement(column));
16886                                                                relation.addSource(new ResultColumnRelationshipElement(
16887                                                                                selectSetResultSetModel.getColumns().get(j)));
16888                                                        }
16889                                                        {
16890                                                                for (TObjectName columnName : pivotClause.getPivotColumnList()) {
16891                                                                        if (table instanceof QueryTable) {
16892                                                                                for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
16893                                                                                        if (getColumnName(columnName).equals(DlineageUtil
16894                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
16895                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16896                                                                                                relation.setEffectType(EffectType.select);
16897                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16898                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16899                                                                                                pivotedColumns.add(tableColumn);
16900                                                                                                break;
16901                                                                                        }
16902                                                                                }
16903                                                                        } else if (table instanceof Table) {
16904                                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
16905                                                                                        if (getColumnName(columnName).equals(DlineageUtil
16906                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
16907                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16908                                                                                                relation.setEffectType(EffectType.select);
16909                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16910                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16911                                                                                                pivotedColumns.add(tableColumn);
16912                                                                                                break;
16913                                                                                        }
16914                                                                                }
16915                                                                        }
16916                                                                }
16917                                                        }
16918                                                }
16919                                        }
16920                                        tables.add(pivotTable);
16921                                        tables.add(table);
16922                                }
16923                        }
16924                }
16925
16926                TPivotClause pivotClause = pivotClauses.get(0);
16927                boolean hasAlias = pivotClause.getAliasClause() != null && pivotClause.getAliasClause().getColumns() != null
16928                                && pivotClause.getAliasClause().getColumns().size() > 0;
16929                if (hasAlias) {
16930                        Alias alias = modelFactory.createAlias(pivotClause.getAliasClause());
16931                        List<TObjectName> aliasColumns = new ArrayList<TObjectName>();
16932                        int index = 0;
16933                        for (int k = 0; k < tables.size(); k++) {
16934                                Object tableItem = tables.get(k);
16935                                if (tableItem instanceof ResultSet) {
16936                                        for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
16937                                                if (pivotedColumns.contains(tableColumn)) {
16938                                                        continue;
16939                                                }
16940                                                if (tableColumn.getColumnObject() instanceof TObjectName) {
16941                                                        aliasColumns.add((TObjectName) tableColumn.getColumnObject());
16942                                                } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
16943                                                        if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
16944                                                                aliasColumns.add(((TResultColumn) tableColumn.getColumnObject()).getFieldAttr());
16945                                                        } else {
16946                                                                TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr();
16947                                                                if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
16948                                                                        TObjectName columnName = new TObjectName();
16949                                                                        columnName.setString(expr.toString());
16950                                                                        aliasColumns.add(columnName);
16951                                                                }
16952                                                        }
16953                                                }
16954                                        }
16955                                } else if (tableItem instanceof Table) {
16956                                        for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
16957                                                if (pivotedColumns.contains(tableColumn)) {
16958                                                        continue;
16959                                                }
16960                                                aliasColumns.add(index, (TObjectName) tableColumn.getColumnObject());
16961                                                index++;
16962                                        }
16963                                }
16964                        }
16965
16966                        IndexedLinkedHashMap<String, ResultColumn> aliasColumnMap = new IndexedLinkedHashMap<String, ResultColumn>();
16967                        int diffCount = pivotClause.getAliasClause().getColumns().size() -  aliasColumns.size();
16968                        for (int k = 0; k < pivotClause.getAliasClause().getColumns().size(); k++) {
16969                                if (pivotClause.getAliasClause().getColumns().size() > aliasColumns.size()) {
16970                                        if (k < diffCount) {
16971                                                continue;
16972                                        }
16973                                        ResultColumn resultColumn = modelFactory.createResultColumn(alias,
16974                                                        pivotClause.getAliasClause().getColumns().getObjectName(k));
16975                                        if ((k - diffCount) < aliasColumns.size()) {
16976                                                aliasColumnMap.put(aliasColumns.get(k - diffCount).toString(), resultColumn);
16977                                        }
16978                                } else {
16979                                        ResultColumn resultColumn = modelFactory.createResultColumn(alias,
16980                                                        pivotClause.getAliasClause().getColumns().getObjectName(k));
16981                                        if (k < aliasColumns.size()) {
16982                                                aliasColumnMap.put(aliasColumns.get(k).toString(), resultColumn);
16983                                        }
16984                                }
16985                        }
16986
16987                        for (int k = 0; k < tables.size(); k++) {
16988                                Object tableItem = tables.get(k);
16989                                if (tableItem instanceof ResultSet) {
16990                                        int resultColumnSize = ((ResultSet) tableItem).getColumns().size();
16991                                        for (int x = 0; x < resultColumnSize; x++) {
16992                                                ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
16993                                                if (pivotedColumns.contains(tableColumn)) {
16994                                                        continue;
16995                                                }
16996                                                if (tableColumn.getColumnObject() instanceof TObjectName) {
16997                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16998                                                        relation.setEffectType(EffectType.select);
16999                                                        relation.setTarget(new ResultColumnRelationshipElement(
17000                                                                        aliasColumnMap.get(tableColumn.getColumnObject().toString())));
17001                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17002                                                } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
17003                                                        if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
17004                                                                ResultColumn targetColumn = aliasColumnMap.get(
17005                                                                                ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr().toString());
17006                                                                if(targetColumn == null) {
17007                                                                        continue;
17008                                                                }
17009                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17010                                                                relation.setEffectType(EffectType.select);
17011                                                                relation.setTarget(new ResultColumnRelationshipElement(targetColumn));
17012                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17013                                                        } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) {
17014                                                                TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr();
17015                                                                if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
17016                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17017                                                                        relation.setEffectType(EffectType.select);
17018                                                                        ResultColumn targetColumn = (ResultColumn) aliasColumnMap
17019                                                                                        .getValueAtIndex(aliasColumnMap.size() - resultColumnSize + x);
17020                                                                        relation.setTarget(new ResultColumnRelationshipElement(targetColumn));
17021                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17022                                                                }
17023                                                        }
17024                                                }
17025                                        }
17026                                } else if (tableItem instanceof Table) {
17027                                        for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17028                                                if (pivotedColumns.contains(tableColumn)) {
17029                                                        continue;
17030                                                }
17031                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17032                                                relation.setEffectType(EffectType.select);
17033                                                relation.setTarget(new ResultColumnRelationshipElement(
17034                                                                aliasColumnMap.get(tableColumn.getColumnObject().toString())));
17035                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17036                                        }
17037                                }
17038                        }
17039
17040                        ResultSet resultSet = modelFactory.createResultSet(stmt,
17041                                        isTopResultSet(stmt) && isShowTopSelectResultSet());
17042                        TResultColumnList columnList = stmt.getResultColumnList();
17043                        for (int i = 0; i < columnList.size(); i++) {
17044                                TResultColumn column = columnList.getResultColumn(i);
17045                                ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
17046                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
17047                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17048                                        if (columnObject.getFieldAttr() != null) {
17049                                                if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
17050                                                        resultColumn.setShowStar(false);
17051                                                        for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
17052                                                                resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject());
17053                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17054                                                                relation.setEffectType(EffectType.select);
17055                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17056                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17057                                                        }
17058                                                } else {
17059                                                        for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
17060                                                                if (getColumnName(columnObject.getFieldAttr())
17061                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17062                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17063                                                                        relation.setEffectType(EffectType.select);
17064                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17065                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17066                                                                        break;
17067                                                                }
17068                                                        }
17069                                                }
17070                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
17071                                                        .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
17072                                                for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
17073                                                        if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand())
17074                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17075                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17076                                                                relation.setEffectType(EffectType.select);
17077                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17078                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17079                                                                break;
17080                                                        }
17081                                                }
17082                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
17083                                                        .getExpressionType() == EExpressionType.function_t) {
17084                                                Function function = (Function) createFunction(columnObject.getExpr().getFunctionCall());
17085                                                for (ResultColumn arg : function.getColumns()) {
17086                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17087                                                        relation.setEffectType(EffectType.select);
17088                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17089                                                        relation.addSource(new ResultColumnRelationshipElement(arg));
17090                                                }
17091                                        }
17092                                }
17093                        }
17094                } else {
17095                        ResultSet resultSet = modelFactory.createResultSet(stmt, isTopResultSet(stmt));
17096                        TResultColumnList columnList = stmt.getResultColumnList();
17097                        for (int i = 0; i < columnList.size(); i++) {
17098                                TResultColumn column = columnList.getResultColumn(i);
17099                                ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
17100                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
17101                                        boolean fromFunction = false;
17102                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17103                                        TObjectName resultColumnFieldAttr = columnObject.getFieldAttr();
17104                                        List<TObjectName> resultColumnNames = new ArrayList<TObjectName>();
17105                                        if (resultColumnFieldAttr != null) {
17106                                                resultColumnNames.add(resultColumnFieldAttr);
17107                                        } else if (columnObject.getExpr() != null
17108                                                        && column.getExpr().getExpressionType() == EExpressionType.function_t) {
17109                                                extractFunctionObjectNames(column.getExpr().getFunctionCall(), resultColumnNames);
17110                                                fromFunction = true;
17111                                        }
17112                                        
17113                                        if (!resultColumnNames.isEmpty()) {
17114                                                for (TObjectName resultColumnName : resultColumnNames) {
17115                                                        if ("*".equals(getColumnName(resultColumnName))) {
17116                                                                resultColumn.setShowStar(false);
17117                                                                int index = 0;
17118                                                                for (int k = 0; k < tables.size(); k++) {
17119                                                                        Object tableItem = tables.get(k);
17120                                                                        if (tableItem instanceof ResultSet && !(tableItem instanceof QueryTable)) {
17121                                                                                for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) {
17122                                                                                        ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
17123                                                                                        if (pivotedColumns.contains(tableColumn)) {
17124                                                                                                continue;
17125                                                                                        }
17126                                                                                        if (tableColumn.getColumnObject() instanceof TObjectName) {
17127                                                                                                resultColumn.bindStarLinkColumn(
17128                                                                                                                (TObjectName) tableColumn.getColumnObject());
17129                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17130                                                                                                relation.setEffectType(EffectType.select);
17131                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17132                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17133                                                                                        } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
17134                                                                                                if (((TResultColumn) tableColumn.getColumnObject())
17135                                                                                                                .getFieldAttr() != null) {
17136                                                                                                        if (tableColumn.hasStarLinkColumn()) {
17137                                                                                                                for (int z = 0; z < tableColumn.getStarLinkColumnList()
17138                                                                                                                                .size(); z++) {
17139                                                                                                                        ResultColumn resultColumn1 = modelFactory
17140                                                                                                                                        .createResultColumn((ResultSet) tableItem,
17141                                                                                                                                                        tableColumn.getStarLinkColumnList().get(z));
17142                                                                                                                        DataFlowRelationship relation = modelFactory
17143                                                                                                                                        .createDataFlowRelation();
17144                                                                                                                        relation.setEffectType(EffectType.select);
17145                                                                                                                        relation.setTarget(
17146                                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
17147                                                                                                                        relation.addSource(
17148                                                                                                                                        new ResultColumnRelationshipElement(resultColumn1));
17149                                                                                                                        tableColumn.getStarLinkColumns().remove(getColumnName(
17150                                                                                                                                        tableColumn.getStarLinkColumnList().get(z)));
17151                                                                                                                        z--;
17152                                                                                                                }
17153                                                                                                        } else {
17154                                                                                                                resultColumn.bindStarLinkColumn(
17155                                                                                                                                ((TResultColumn) tableColumn.getColumnObject())
17156                                                                                                                                                .getFieldAttr());
17157                                                                                                                DataFlowRelationship relation = modelFactory
17158                                                                                                                                .createDataFlowRelation();
17159                                                                                                                relation.setEffectType(EffectType.select);
17160                                                                                                                relation.setTarget(
17161                                                                                                                                new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject())
17162                                                                                                                                                .getFieldAttr()));
17163                                                                                                                relation.addSource(
17164                                                                                                                                new ResultColumnRelationshipElement(tableColumn));
17165                                                                                                        }
17166                                                                                                } else if (((TResultColumn) tableColumn.getColumnObject())
17167                                                                                                                .getExpr() != null) {
17168                                                                                                        TExpression expr = ((TResultColumn) tableColumn.getColumnObject())
17169                                                                                                                        .getExpr();
17170                                                                                                        if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
17171                                                                                                                TObjectName columnName = new TObjectName();
17172                                                                                                                columnName.setString(expr.toString());
17173                                                                                                                resultColumn.bindStarLinkColumn(columnName);
17174                                                                                                                DataFlowRelationship relation = modelFactory
17175                                                                                                                                .createDataFlowRelation();
17176                                                                                                                relation.setEffectType(EffectType.select);
17177                                                                                                                relation.setTarget(
17178                                                                                                                                new ResultColumnRelationshipElement(resultColumn, columnName));
17179                                                                                                                relation.addSource(
17180                                                                                                                                new ResultColumnRelationshipElement(tableColumn));
17181                                                                                                        }
17182                                                                                                }
17183                                                                                        }
17184                                                                                }
17185                                                                        } else if (tableItem instanceof Table) {
17186                                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17187                                                                                        if (pivotedColumns.contains(tableColumn)) {
17188                                                                                                continue;
17189                                                                                        }
17190                                                                                        resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(),
17191                                                                                                        index);
17192                                                                                        index++;
17193                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17194                                                                                        relation.setEffectType(EffectType.select);
17195                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17196                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17197                                                                                }
17198                                                                        } else if (tableItem instanceof QueryTable) {
17199                                                                                for (ResultColumn tableColumn : ((QueryTable) tableItem).getColumns()) {
17200                                                                                        if (pivotedColumns.contains(tableColumn)) {
17201                                                                                                continue;
17202                                                                                        }
17203                                                                                        TObjectName column1 = new TObjectName();
17204                                                                                        column1.setString(tableColumn.getName());
17205                                                                                        resultColumn.bindStarLinkColumn(column1, index);
17206                                                                                        index++;
17207                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17208                                                                                        relation.setEffectType(EffectType.select);
17209                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, column1));
17210                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn), false);
17211                                                                                }
17212                                                                        }
17213                                                                }
17214                                                        } else {
17215                                                                ResultColumn pivotedTableColumn = getPivotedTableColumn(pivotedTable, resultColumnName);
17216                                                                        if (pivotedTableColumn != null) {
17217                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17218                                                                                relation.setEffectType(EffectType.select);
17219                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17220                                                                                relation.addSource(new ResultColumnRelationshipElement(pivotedTableColumn));
17221                                                                        } else {
17222                                                                                for (int k = 0; k < tables.size(); k++) {
17223                                                                                        Object tableItem = tables.get(k);
17224                                                                                        if (tableItem instanceof ResultSet) {
17225                                                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
17226                                                                                                        if (DlineageUtil
17227                                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()).equals(getColumnName(resultColumnName))) {
17228                                                                                                                if (fromFunction) {
17229                                                                                                                        Function function = (Function)createPivotedFunction(column.getExpr().getFunctionCall(), tableColumn);
17230                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17231                                                                                                                        relation.setEffectType(EffectType.select);
17232                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17233                                                                                                                        if (function.getColumns() != null && !function.getColumns().isEmpty()) {
17234                                                                                                                                for (ResultColumn functionColumn : function.getColumns()) {
17235                                                                                                                                        relation.addSource(new ResultColumnRelationshipElement(functionColumn));
17236                                                                                                                                }
17237                                                                                                                        }
17238                                                                                                                } else {
17239                                                                                                                        DataFlowRelationship relation = modelFactory
17240                                                                                                                                        .createDataFlowRelation();
17241                                                                                                                        relation.setEffectType(EffectType.select);
17242                                                                                                                        relation.setTarget(
17243                                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
17244                                                                                                                        relation.addSource(
17245                                                                                                                                        new ResultColumnRelationshipElement(tableColumn));
17246                                                                                                                }
17247                                                                                                                break;
17248                                                                                                        }
17249                                                                                                }
17250                                                                                        } else if (tableItem instanceof Table) {
17251                                                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17252                                                                                                        if (getColumnName(resultColumnName).equals(DlineageUtil
17253                                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17254                                                                                                                DataFlowRelationship relation = modelFactory
17255                                                                                                                                .createDataFlowRelation();
17256                                                                                                                relation.setEffectType(EffectType.select);
17257                                                                                                                relation.setTarget(
17258                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
17259                                                                                                                relation.addSource(
17260                                                                                                                                new TableColumnRelationshipElement(tableColumn));
17261                                                                                                                break;
17262                                                                                                        }
17263                                                                                                }
17264                                                                                        }
17265                                                                                }
17266                                                                        }
17267                                                                }
17268                                                }
17269                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
17270                                                        .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
17271                                                for (int k = 0; k < tables.size(); k++) {
17272                                                        Object tableItem = tables.get(k);
17273                                                        if (tableItem instanceof ResultSet) {
17274                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
17275                                                                        if (columnObject.getExpr().getRightOperand().getObjectOperand() != null
17276                                                                                        && getColumnName(
17277                                                                                                        columnObject.getExpr().getRightOperand().getObjectOperand())
17278                                                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(
17279                                                                                                                                        tableColumn.getName()))) {
17280                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17281                                                                                relation.setEffectType(EffectType.select);
17282                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17283                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17284                                                                                break;
17285                                                                        } else if (columnObject.getExpr().getRightOperand()
17286                                                                                        .getExpressionType() == EExpressionType.function_t) {
17287                                                                                List<TExpression> expressions = new ArrayList<TExpression>();
17288                                                                                getFunctionExpressions(expressions, new ArrayList<TExpression>(),
17289                                                                                                columnObject.getExpr().getRightOperand().getFunctionCall());
17290                                                                                for (int j = 0; j < expressions.size(); j++) {
17291                                                                                        columnsInExpr visitor = new columnsInExpr();
17292                                                                                        expressions.get(j).inOrderTraverse(visitor);
17293                                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
17294                                                                                        if (objectNames == null) {
17295                                                                                                continue;
17296                                                                                        }
17297                                                                                        for (TObjectName columnName : objectNames) {
17298                                                                                                if (getColumnName(columnName).equals(DlineageUtil
17299                                                                                                                .getIdentifierNormalColumnName(tableColumn.getName()))) {
17300                                                                                                        DataFlowRelationship relation = modelFactory
17301                                                                                                                        .createDataFlowRelation();
17302                                                                                                        relation.setEffectType(EffectType.select);
17303                                                                                                        relation.setTarget(
17304                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
17305                                                                                                        relation.addSource(
17306                                                                                                                        new ResultColumnRelationshipElement(tableColumn));
17307                                                                                                        break;
17308                                                                                                }
17309                                                                                        }
17310                                                                                }
17311                                                                        }
17312                                                                }
17313                                                        } else if (tableItem instanceof Table) {
17314                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17315                                                                        if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand())
17316                                                                                        .equals(DlineageUtil
17317                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17318                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17319                                                                                relation.setEffectType(EffectType.select);
17320                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17321                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17322                                                                                break;
17323                                                                        }
17324                                                                }
17325                                                        }
17326                                                }
17327                                        }
17328                                }
17329                        }
17330                }
17331
17332                analyzeSelectIntoClause(stmt);
17333        }
17334
17335        private Function createPivotedFunction(TFunctionCall functionCall, ResultColumn sourceColumn) {
17336                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
17337                ResultColumn column = modelFactory.createFunctionResultColumn(function,
17338                                ((TFunctionCall) functionCall).getFunctionName());
17339                if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) {
17340                        // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP
17341                        // COUNT特殊处理,不和参数关联
17342                        if (option.isShowCountTableColumn()) {
17343                                analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn);
17344                        }
17345                } else {
17346                        analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn);
17347                        Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function));
17348                        if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) {
17349                                ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next();
17350                                if (functionTableModel.getColumns() != null) {
17351                                        for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
17352                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17353                                                        relation.setEffectType(EffectType.select);
17354                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
17355                                                        relation.addSource(new ResultColumnRelationshipElement(
17356                                                                        functionTableModel.getColumns().get(j)));
17357                                        }
17358                                }
17359                        }
17360                }
17361                return function;
17362        }
17363
17364        private void analyzePivotedFunctionArgumentsDataFlowRelation(ResultColumn column, TFunctionCall functionCall,
17365                        ResultColumn sourceColumn) {
17366                List<TExpression> directExpressions = new ArrayList<TExpression>();
17367                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
17368
17369                getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
17370
17371                for (int j = 0; j < directExpressions.size(); j++) {
17372                        columnsInExpr visitor = new columnsInExpr();
17373                        directExpressions.get(j).inOrderTraverse(visitor);
17374
17375                        List<TObjectName> objectNames = visitor.getObjectNames();
17376                        List<TParseTreeNode> constants = visitor.getConstants();
17377
17378                        if (objectNames != null) {
17379                                for (TObjectName name : objectNames) {
17380                                        if (DlineageUtil.compareColumnIdentifier(name.toString(), sourceColumn.getName())) {
17381                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17382                                                relation.setEffectType(EffectType.select);
17383                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17384                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
17385                                        }
17386                                }
17387                        }
17388                        if (constants != null) {
17389                                for (TParseTreeNode name : constants) {
17390                                        if (name.toString().equals(sourceColumn.getName())) {
17391                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17392                                                relation.setEffectType(EffectType.select);
17393                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17394                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
17395                                        }
17396                                }
17397                        }
17398                }
17399        }
17400        
17401        private void extractFunctionObjectNames(TFunctionCall functionCall, List<TObjectName> resultColumnNames) {
17402                List<TExpression> directExpressions = new ArrayList<TExpression>();
17403                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
17404
17405                getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
17406
17407                for (int j = 0; j < directExpressions.size(); j++) {
17408                        columnsInExpr visitor = new columnsInExpr();
17409                        directExpressions.get(j).inOrderTraverse(visitor);
17410
17411                        List<TObjectName> objectNames = visitor.getObjectNames();
17412                        List<TParseTreeNode> functions = visitor.getFunctions();
17413                        List<TParseTreeNode> constants = visitor.getConstants(); 
17414
17415                        if (objectNames != null) {
17416                                resultColumnNames.addAll(objectNames);
17417                        }
17418                        
17419                        if (constants != null) {
17420                                for(TParseTreeNode item: constants) {
17421                                        if(item instanceof TConstant && ((TConstant) item).getLiteralType().getText().equals(ELiteralType.string_et.getText())) {
17422                                                TObjectName object = new TObjectName();
17423                                                object.setString(item.toString());
17424                                                resultColumnNames.add(object);
17425                                        }
17426                                }
17427                        }
17428
17429                        if (functions != null && !functions.isEmpty()) {
17430                                for (TParseTreeNode function : functions) {
17431                                        if (function instanceof TFunctionCall) {
17432                                                extractFunctionObjectNames((TFunctionCall) function, resultColumnNames);
17433                                        }
17434                                }
17435                        }
17436                }
17437        }
17438
17439        private String getResultColumnString(TResultColumn resultColumn) {
17440                if (resultColumn.getAliasClause() != null) {
17441                        return resultColumn.getAliasClause().toString();
17442                }
17443                return resultColumn.toString();
17444        }
17445
17446        private void analyzeBigQueryUnnest(TSelectSqlStatement stmt, TTable table) {
17447                Table unnestTable = modelFactory.createTableFromCreateDDL(table, false, getTempTableName(table));
17448                unnestTable.setSubType(SubType.unnest);
17449                TUnnestClause clause = table.getUnnestClause();
17450                TExpression arrayExpr = clause.getArrayExpr();
17451                if (arrayExpr == null){
17452                        if (clause.getColumns() != null) {
17453                                for (TObjectName column : clause.getColumns()) {
17454                                        if (clause.getDerivedColumnList() != null) {
17455                                                unnestTable.setCreateTable(true);
17456                                                for (int i = 0; i < clause.getDerivedColumnList().size(); i++) {
17457                                                        TObjectName columnName = new TObjectName();
17458                                                        columnName.setString(column.getColumnNameOnly() + "."
17459                                                                        + clause.getDerivedColumnList().getObjectName(i).getColumnNameOnly());
17460                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true);
17461                                                        List<TObjectName> columns = new ArrayList<TObjectName>();
17462                                                        columns.add(column);
17463                                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
17464                                                }
17465                                        }
17466                                        else {
17467                                                unnestTable.setCreateTable(true);
17468                                                boolean find = false;
17469                                                if (column.getSourceTable() != null && modelManager.getModel(column.getSourceTable()) instanceof Table) {
17470                                                        Table sourceTable = (Table)modelManager.getModel(column.getSourceTable());
17471                                                        if(sourceTable!=null) {
17472                                                                for(TableColumn tableColumn: sourceTable.getColumns()) {
17473                                                                        if(tableColumn.isStruct()) {
17474                                                                                List<String> names = SQLUtil.parseNames(tableColumn.getName());
17475                                                                                if (names.get(0).equalsIgnoreCase(column.getColumnNameOnly())) {
17476                                                                                        TObjectName columnName = new TObjectName();
17477                                                                                        columnName.setString(tableColumn.getName());
17478                                                                                        TableColumn unnestTableColumn = modelFactory.createTableColumn(unnestTable,
17479                                                                                                        columnName, true);
17480                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17481                                                                                        relation.setEffectType(EffectType.select);
17482                                                                                        relation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
17483                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17484                                                                                        find = true;
17485                                                                                }
17486                                                                        }
17487                                                                }
17488                                                        }
17489                                                }
17490                                                if (!find) {
17491                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, column, true);
17492                                                        List<TObjectName> columns = new ArrayList<TObjectName>();
17493                                                        columns.add(column);
17494                                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
17495                                                }
17496                                        }
17497                                }
17498                        }
17499                        return;
17500                }
17501                List<TExpression> expressions = new ArrayList<TExpression>();
17502                TExpressionList values = arrayExpr.getExprList();
17503                if (values == null) {
17504                        expressions.add(arrayExpr);
17505                }
17506                else {
17507                        for(TExpression value: values) {
17508                                expressions.add(value);
17509                        }
17510                }
17511                for (TExpression value : expressions) {
17512                        unnestTable.setCreateTable(true);
17513                        if (value.getExpressionType() == EExpressionType.simple_object_name_t) {
17514                                if (table.getAliasClause() != null) {
17515                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
17516                                                        table.getAliasClause().getAliasName(), true);
17517                                        columnsInExpr visitor = new columnsInExpr();
17518                                        value.inOrderTraverse(visitor);
17519                                        List<TObjectName> columns = visitor.getObjectNames();
17520                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
17521                                } else {
17522                                        TResultColumnList resultColumnList = stmt.getResultColumnList();
17523                                        for (int i = 0; i < resultColumnList.size(); i++) {
17524                                                TObjectName firstColumn = new TObjectName();
17525                                                firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly());
17526                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
17527                                                columnsInExpr visitor = new columnsInExpr();
17528                                                value.inOrderTraverse(visitor);
17529                                                List<TObjectName> columns = visitor.getObjectNames();
17530                                                analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
17531                                        }
17532                                }
17533                        } else if (value.getExpressionType() == EExpressionType.function_t) {
17534                                if (table.getAliasClause() != null) {
17535                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
17536                                                        table.getAliasClause().getAliasName(), true);
17537                                        columnsInExpr visitor = new columnsInExpr();
17538                                        value.inOrderTraverse(visitor);
17539                                        List<TParseTreeNode> functions = visitor.getFunctions();
17540                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.select, null);
17541                                } else {
17542                                        TResultColumnList resultColumnList = stmt.getResultColumnList();
17543                                        for (int i = 0; i < resultColumnList.size(); i++) {
17544                                                TObjectName firstColumn = new TObjectName();
17545                                                firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly());
17546                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
17547                                                columnsInExpr visitor = new columnsInExpr();
17548                                                value.inOrderTraverse(visitor);
17549                                                List<TObjectName> columns = visitor.getObjectNames();
17550                                                analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
17551                                        }
17552                                }
17553                        } else if (value.getExpressionType() == EExpressionType.simple_constant_t) {
17554                                if (table.getAliasClause() != null) {
17555                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
17556                                                        table.getAliasClause().getAliasName(), true);
17557                                        columnsInExpr visitor = new columnsInExpr();
17558                                        value.inOrderTraverse(visitor);
17559                                        List<TParseTreeNode> constants = visitor.getConstants();
17560                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
17561                                } else {
17562                                        TObjectName firstColumn = new TObjectName();
17563                                        firstColumn.setString("f0_");
17564                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
17565                                        columnsInExpr visitor = new columnsInExpr();
17566                                        value.inOrderTraverse(visitor);
17567                                        List<TParseTreeNode> constants = visitor.getConstants();
17568                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
17569                                }
17570                        } else if (value.getExpressionType() == EExpressionType.list_t) {
17571                                if (arrayExpr.getTypeName() != null && arrayExpr.getTypeName().getColumnDefList() != null) {
17572                                        for (int i = 0; i < arrayExpr.getTypeName().getColumnDefList().size(); i++) {
17573                                                TColumnDefinition column = arrayExpr.getTypeName().getColumnDefList().getColumn(i);
17574                                                if (column != null && column.getColumnName() != null) {
17575                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
17576                                                                        column.getColumnName(), true);
17577                                                        columnsInExpr visitor = new columnsInExpr();
17578                                                        value.getExprList().getExpression(i).inOrderTraverse(visitor);
17579                                                        List<TParseTreeNode> constants = visitor.getConstants();
17580                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
17581                                                }
17582                                        }
17583                                } else {
17584                                        for (int i = 0; i < value.getExprList().size(); i++) {
17585                                                TObjectName firstColumn = new TObjectName();
17586                                                firstColumn.setString("f" + i + "_");
17587                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
17588                                                columnsInExpr visitor = new columnsInExpr();
17589                                                value.getExprList().getExpression(i).inOrderTraverse(visitor);
17590                                                List<TParseTreeNode> constants = visitor.getConstants();
17591                                                analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
17592                                        }
17593                                }
17594                        } else if (value.getExpressionType() == EExpressionType.subquery_t) {
17595                                analyzeSelectStmt(value.getSubQuery());
17596                                ResultSet resultSet = (ResultSet) modelManager.getModel(value.getSubQuery());
17597                                if (resultSet != null) {
17598                                        for (int i = 0; i < resultSet.getColumns().size(); i++) {
17599                                                TObjectName columnName =  new TObjectName();
17600                                                if(resultSet.getColumns().get(i).getAlias()!=null) {
17601                                                        columnName.setString(resultSet.getColumns().get(i).getAlias());
17602                                                }
17603                                                else {
17604                                                        columnName.setString(getColumnName(resultSet.getColumns().get(i).getName()));
17605                                                }
17606                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true);
17607                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17608                                                relation.setEffectType(EffectType.select);
17609                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17610                                                relation.addSource(
17611                                                                new ResultColumnRelationshipElement(resultSet.getColumns().get(i)));
17612                                        }
17613                                }
17614                        }
17615                }
17616        }
17617
17618        private void analyzePrestoUnnest(TSelectSqlStatement stmt, TTable table) {
17619                List<Table> tables = new ArrayList<Table>();
17620                TTable targetTable = stmt.getTables().getTable(0);
17621                Table stmtTable = modelFactory.createTable(targetTable);
17622                Object sourceTable = null;
17623                if (targetTable.getSubquery() != null) {
17624                        analyzeSelectStmt(targetTable.getSubquery());
17625                        if (targetTable.getSubquery().isCombinedQuery()) {
17626                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(targetTable.getSubquery());
17627                                sourceTable = sourceResultSet;
17628                        } else if (targetTable.getSubquery().getResultColumnList() != null) {
17629                                ResultSet sourceResultSet = (ResultSet) modelManager
17630                                                .getModel(targetTable.getSubquery().getResultColumnList());
17631                                sourceTable = sourceResultSet;
17632                        } else if (targetTable.getSubquery().getValueClause() != null) {
17633                                List<TResultColumnList> rowList = targetTable.getSubquery().getValueClause().getRows();
17634                                if (rowList != null && rowList.size() > 0) {
17635                                        Table valuesTable = modelFactory.createTableByName("Values-Table", true);
17636                                        int columnCount = rowList.get(0).size();
17637                                        for (int j = 1; j <= columnCount; j++) {
17638                                                TObjectName columnName = new TObjectName();
17639                                                TResultColumn columnObject = rowList.get(0).getResultColumn(j - 1);
17640                                                if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) {
17641                                                        columnName.setString(columnObject.getExpr().getLeftOperand().toString());
17642                                                } else {
17643                                                        columnName.setString(columnObject.getExpr().toString());
17644                                                }
17645                                                modelFactory.createTableColumn(valuesTable, columnName, true);
17646                                        }
17647                                        valuesTable.setCreateTable(true);
17648                                        valuesTable.setSubType(SubType.values_table);
17649                                        sourceTable = valuesTable;
17650                                }
17651                        }
17652                }
17653                tables.add(stmtTable);
17654                Table unnestTable = modelFactory.createTable(table);
17655                unnestTable.setSubType(SubType.unnest);
17656                tables.add(unnestTable);
17657                if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null
17658                                && table.getUnnestClause().getColumns() != null) {
17659                        int unnestTableSize = table.getUnnestClause().getColumns().size();
17660                        for (int i = 0; i < table.getAliasClause().getColumns().size(); i++) {
17661                                TableColumn sourceColumn = null;
17662                                if (unnestTableSize > i) {
17663                                        sourceColumn = modelFactory.createTableColumn(stmtTable,
17664                                                        table.getUnnestClause().getColumns().getObjectName(i), true);
17665                                        if (sourceTable instanceof Table) {
17666                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17667                                                relation.setEffectType(EffectType.select);
17668                                                relation.setTarget(new TableColumnRelationshipElement(sourceColumn));
17669                                                relation.addSource(
17670                                                                new TableColumnRelationshipElement(((Table) sourceTable).getColumns().get(i)));
17671                                        } else if (sourceTable instanceof ResultSet) {
17672                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17673                                                relation.setEffectType(EffectType.select);
17674                                                relation.setTarget(new TableColumnRelationshipElement(sourceColumn));
17675                                                relation.addSource(
17676                                                                new ResultColumnRelationshipElement(((ResultSet) sourceTable).getColumns().get(i)));
17677                                        }
17678                                } else {
17679                                        sourceColumn = modelFactory.createTableColumn(stmtTable,
17680                                                        table.getUnnestClause().getColumns().getObjectName(unnestTableSize - 1), true);
17681                                }
17682                                TableColumn targetColumn = modelFactory.createTableColumn(unnestTable,
17683                                                table.getAliasClause().getColumns().getObjectName(i), true);
17684                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17685                                relation.setEffectType(EffectType.select);
17686                                relation.setTarget(new TableColumnRelationshipElement(targetColumn));
17687                                relation.addSource(new TableColumnRelationshipElement(sourceColumn));
17688                        }
17689                }
17690
17691                ResultSet resultSet = modelFactory.createResultSet(stmt,
17692                                isTopResultSet(stmt) && isShowTopSelectResultSet());
17693                TResultColumnList columnList = stmt.getResultColumnList();
17694                for (int i = 0; i < columnList.size(); i++) {
17695                        TResultColumn column = columnList.getResultColumn(i);
17696                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
17697                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
17698                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17699                                if (columnObject.getFieldAttr() != null) {
17700                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
17701                                                for (int k = 0; k < tables.size(); k++) {
17702                                                        Table tableItem = tables.get(k);
17703                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
17704                                                                resultColumn.bindStarLinkColumn(tableColumn.getColumnObject());
17705                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17706                                                                relation.setEffectType(EffectType.select);
17707                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject()));
17708                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17709                                                        }
17710                                                }
17711                                        } else {
17712                                                boolean match = false;
17713                                                for (int k = 0; k < tables.size(); k++) {
17714                                                        Table tableItem = tables.get(k);
17715                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
17716                                                                if (getColumnName(columnObject.getFieldAttr())
17717                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17718                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17719                                                                        relation.setEffectType(EffectType.select);
17720                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17721                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17722                                                                        match = true;
17723                                                                }
17724                                                        }
17725                                                }
17726                                                if (!match) {
17727                                                        TableColumn tableColumn = modelFactory.createTableColumn(stmtTable,
17728                                                                        columnObject.getFieldAttr(), false);
17729                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17730                                                        relation.setEffectType(EffectType.select);
17731                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17732                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17733                                                }
17734                                        }
17735                                }
17736                        }
17737                }
17738        }
17739
17740        private void analyzeLateralView(TSelectSqlStatement stmt, TTable table, ArrayList<TLateralView> lateralViews) {
17741                List<Object> tables = new ArrayList<Object>();
17742                Object stmtTable = null;
17743                if(table.getSubquery()!=null) {
17744                        stmtTable = modelFactory.createQueryTable(table);
17745                        tables.add(stmtTable);
17746                }
17747                else {
17748                        stmtTable = modelFactory.createTable(table);
17749                        tables.add(stmtTable);
17750                }
17751                for (int i = 0; i < lateralViews.size(); i++) {
17752                        TLateralView lateralView = lateralViews.get(i);
17753                        TFunctionCall functionCall = lateralView.getUdtf();
17754                        List<TExpression> expressions = new ArrayList<TExpression>();
17755                        if (functionCall == null) {
17756                                continue;
17757                        }
17758                        Function function = modelFactory.createFunction(functionCall);
17759                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
17760                                        ((TFunctionCall) functionCall).getFunctionName());
17761
17762                        Table lateralTable = null;
17763                        if (lateralView.getTableAlias() != null) {
17764                                lateralTable = modelFactory.createTableByName(lateralView.getTableAlias().getAliasName(), true);
17765                        } else {
17766                                lateralTable = modelFactory.createTableByName(functionCall.toString(), true);
17767                        }
17768
17769                        for (int j = 0; j < lateralView.getColumnAliasList().size(); j++) {
17770                                TObjectName viewColumn = lateralView.getColumnAliasList().getObjectName(j);
17771                                TableColumn tableColumn = modelFactory.createTableColumn(lateralTable, viewColumn, true);
17772
17773                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17774                                relation.setEffectType(EffectType.select);
17775                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17776                                relation.addSource(new ResultColumnRelationshipElement(column));
17777                        }
17778
17779                        getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall);
17780                        for (int j = 0; j < expressions.size(); j++) {
17781                                columnsInExpr visitor = new columnsInExpr();
17782                                expressions.get(j).inOrderTraverse(visitor);
17783                                List<TObjectName> objectNames = visitor.getObjectNames();
17784                                if (objectNames == null) {
17785                                        continue;
17786                                }
17787                                for (TObjectName columnName : objectNames) {
17788                                        boolean match = false;
17789                                        for (int k = 0; k < tables.size(); k++) {
17790                                                Object item = tables.get(k);
17791                                                if(item instanceof Table) {
17792                                                        Table tableItem = (Table)item;
17793                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
17794                                                                if (getColumnName(columnName)
17795                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17796                                                                        match = true;
17797                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17798                                                                        relation.setEffectType(EffectType.select);
17799                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
17800                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17801                                                                }
17802                                                        }
17803                                                }
17804                                                else {
17805                                                        ResultSet tableItem = (ResultSet)item;
17806                                                        for (ResultColumn tableColumn : tableItem.getColumns()) {
17807                                                                if (getColumnName(columnName)
17808                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17809                                                                        match = true;
17810                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17811                                                                        relation.setEffectType(EffectType.select);
17812                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
17813                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17814                                                                }
17815                                                        }
17816                                                }
17817                                        }
17818                                        if (!match) {
17819                                                if(stmtTable instanceof Table) {
17820                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable, columnName, false);
17821                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17822                                                        relation.setEffectType(EffectType.select);
17823                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
17824                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17825                                                }
17826                                                else {
17827                                                        ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable, columnName, false);
17828                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17829                                                        relation.setEffectType(EffectType.select);
17830                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
17831                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17832                                                }
17833                                        }
17834                                }
17835                                List<TParseTreeNode> constants = visitor.getConstants();
17836                                if (!constants.isEmpty()) {
17837                                        if (option.isShowConstantTable()) {
17838                                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
17839                                                for (TParseTreeNode constant : constants) {
17840                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17841                                                        relation.setEffectType(EffectType.select);
17842                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
17843                                                        if (constant instanceof TConstant) {
17844                                                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
17845                                                                                (TConstant) constant);
17846                                                                relation.addSource(new ConstantRelationshipElement(constantColumn));
17847                                                        } else if (constant instanceof TObjectName) {
17848                                                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
17849                                                                                (TObjectName) constant, false);
17850                                                                relation.addSource(new ConstantRelationshipElement(constantColumn));
17851                                                        }
17852                                                }
17853                                        }
17854                                }
17855                                
17856                                List<TParseTreeNode> functions = visitor.getFunctions();
17857                                if (functions != null && !functions.isEmpty()) {
17858                                        analyzeFunctionDataFlowRelation(column, functions, EffectType.function);
17859                                }
17860                        }
17861                        tables.add(lateralTable);
17862                }
17863
17864                ResultSet resultSet = modelFactory.createResultSet(stmt,
17865                                isTopResultSet(stmt) && isShowTopSelectResultSet());
17866                TResultColumnList columnList = stmt.getResultColumnList();
17867                for (int i = 0; i < columnList.size(); i++) {
17868                        TResultColumn column = columnList.getResultColumn(i);
17869                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
17870                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
17871                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17872                                if (columnObject.getFieldAttr() != null) {
17873                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
17874                                                for (int k = 0; k < tables.size(); k++) {
17875                                                        Object item = tables.get(k);
17876                                                        if(item instanceof Table) {
17877                                                                Table tableItem = (Table)item;
17878                                                                for (TableColumn tableColumn : tableItem.getColumns()) {
17879                                                                        resultColumn.bindStarLinkColumn(tableColumn.getColumnObject());
17880                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17881                                                                        relation.setEffectType(EffectType.select);
17882                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject()));
17883                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17884                                                                }
17885                                                        }
17886                                                        else {
17887                                                                ResultSet tableItem = (ResultSet)item;
17888                                                                for (ResultColumn tableColumn : tableItem.getColumns()) {
17889                                                                        TObjectName linkColumn = new TObjectName();
17890                                                                        linkColumn.setString(tableColumn.getName());
17891                                                                        resultColumn.bindStarLinkColumn(linkColumn);
17892                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17893                                                                        relation.setEffectType(EffectType.select);
17894                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, linkColumn));
17895                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17896                                                                }
17897                                                        }
17898                                                }
17899                                        } else {
17900                                                boolean match = false;
17901                                                for (int k = 0; k < tables.size(); k++) {
17902                                                        Object item = tables.get(k);
17903                                                        if(item instanceof Table) {
17904                                                                Table tableItem = (Table)item;
17905                                                                for (TableColumn tableColumn : tableItem.getColumns()) {
17906                                                                        if (getColumnName(columnObject.getFieldAttr())
17907                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17908                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17909                                                                                relation.setEffectType(EffectType.select);
17910                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17911                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17912                                                                                match = true;
17913                                                                        }
17914                                                                }
17915                                                        }
17916                                                        else {
17917                                                                ResultSet tableItem = (ResultSet)item;
17918                                                                for (ResultColumn tableColumn : tableItem.getColumns()) {
17919                                                                        if (getColumnName(columnObject.getFieldAttr())
17920                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17921                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17922                                                                                relation.setEffectType(EffectType.select);
17923                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17924                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17925                                                                                match = true;
17926                                                                        }
17927                                                                }
17928                                                        }
17929                                                }
17930                                                if (!match) {
17931                                                        if(stmtTable instanceof Table) {
17932                                                                TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable,
17933                                                                                columnObject.getFieldAttr(), false);
17934                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17935                                                                relation.setEffectType(EffectType.select);
17936                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17937                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17938                                                        }
17939                                                        else {
17940                                                                ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable,
17941                                                                                columnObject.getFieldAttr(), false);
17942                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17943                                                                relation.setEffectType(EffectType.select);
17944                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17945                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17946                                                        }
17947                                                }
17948                                        }
17949                                }
17950                                else if (columnObject.getExpr() != null
17951                                                && columnObject.getExpr().getExpressionType() == EExpressionType.function_t) {
17952                                        analyzeResultColumn(column, EffectType.select);
17953                                        for (int k = 0; k < tables.size(); k++) {
17954                                                Object item = tables.get(k);
17955                                                if (item instanceof Table) {
17956                                                        Table tableItem = (Table) item;
17957                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
17958                                                                if (getColumnName(resultColumn.getName()).equals(
17959                                                                                DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17960                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17961                                                                        relation.setEffectType(EffectType.select);
17962                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17963                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17964                                                                }
17965                                                        }
17966                                                } else {
17967                                                        ResultSet tableItem = (ResultSet) item;
17968                                                        for (ResultColumn tableColumn : tableItem.getColumns()) {
17969                                                                if (getColumnName(resultColumn.getName()).equals(
17970                                                                                DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17971                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17972                                                                        relation.setEffectType(EffectType.select);
17973                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17974                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17975                                                                }
17976                                                        }
17977                                                }
17978                                        }
17979                                }
17980                        }
17981                }
17982        }
17983
17984        private boolean isFromFunction(TObjectName object) {
17985
17986                Stack<TParseTreeNode> nodes = object.getStartToken().getNodesStartFromThisToken();
17987                if (nodes != null) {
17988                        for (int i = 0; i < nodes.size(); i++) {
17989                                if (nodes.get(i) instanceof TFunctionCall) {
17990                                        return true;
17991                                }
17992                        }
17993                }
17994                return false;
17995        }
17996
17997        private TResultColumnList getResultColumnList(TSelectSqlStatement stmt) {
17998                if (stmt.isCombinedQuery()) {
17999                        TResultColumnList columns = getResultColumnList(stmt.getLeftStmt());
18000                        if (columns != null) {
18001                                return columns;
18002                        }
18003                        return getResultColumnList(stmt.getRightStmt());
18004                } else {
18005                        return stmt.getResultColumnList();
18006                }
18007        }
18008
18009        private void createPseudoImpactRelation(TCustomSqlStatement stmt, ResultSet resultSetModel, EffectType effectType) {
18010                if (stmt.getTables() != null) {
18011                        for (int i = 0; i < stmt.getTables().size(); i++) {
18012                                TTable table = stmt.getTables().getTable(i);
18013                                if (modelManager.getModel(table) instanceof ResultSet) {
18014                                        ResultSet tableModel = (ResultSet) modelManager.getModel(table);
18015                                        if (tableModel != resultSetModel && !tableModel.getRelationRows().getHoldRelations().isEmpty()) {
18016                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
18017                                                impactRelation.setEffectType(effectType);
18018                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18019                                                                tableModel.getRelationRows()));
18020                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18021                                                                resultSetModel.getRelationRows()));
18022                                        }
18023                                } else if (modelManager.getModel(table) instanceof Table) {
18024                                        Table tableModel = (Table) modelManager.getModel(table);
18025                                        if (!tableModel.getRelationRows().getHoldRelations().isEmpty()) {
18026                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
18027                                                impactRelation.setEffectType(effectType);
18028                                                impactRelation.addSource(
18029                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
18030                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18031                                                                resultSetModel.getRelationRows()));
18032                                        }
18033                                }
18034                        }
18035                }
18036        }
18037
18038        private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions,
18039                        EffectType effectType) {
18040                for (int i = 0; i < functions.size(); i++) {
18041                        TParseTreeNode functionCall = functions.get(i);
18042                        if (functionCall instanceof TFunctionCall) {
18043                                String functionName = DlineageUtil.getIdentifierNormalTableName(
18044                                                DlineageUtil.getFunctionNameWithArgNum((TFunctionCall) functionCall));
18045                                Procedure procedure = modelManager.getProcedureByName(functionName);
18046                                if (procedure != null) {
18047                                        String procedureParent = getProcedureParentName(stmtStack.peek());
18048                                        if (procedureParent != null) {
18049                                                Procedure caller = modelManager
18050                                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
18051                                                if (caller != null) {
18052                                                        CallRelationship callRelation = modelFactory.createCallRelation();
18053                                                        callRelation.setCallObject(functionCall);
18054                                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
18055                                                        callRelation.addSource(new ProcedureRelationshipElement(procedure));
18056                                                        if (isBuiltInFunctionName(((TFunctionCall)functionCall).getFunctionName())||isKeyword(((TFunctionCall)functionCall).getFunctionName())) {
18057                                                                callRelation.setBuiltIn(true);
18058                                                        }
18059                                                }
18060                                        }
18061                                        if (procedure.getProcedureObject() instanceof TCreateFunctionStmt) {
18062                                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt)procedure.getProcedureObject();
18063                                                TTypeName dataType = createFunction.getReturnDataType();
18064                                                if (dataType!=null && dataType.getTypeOfList() != null && dataType.getTypeOfList().getColumnDefList() != null) {
18065                                                        Object modelObject = modelManager.getModel(gspObject);
18066                                                        if(modelObject instanceof ResultColumn) {
18067                                                                ResultColumn resultColumn = (ResultColumn)modelObject;
18068                                                                ResultSet resultSet = resultColumn.getResultSet();
18069                                                                for (int j = 0; j < dataType.getTypeOfList().getColumnDefList().size(); j++) {
18070                                                                        TObjectName columnName = new TObjectName();
18071                                                                        if( dataType.getDataType() == EDataType.array_t) {
18072                                                                                columnName.setString(resultColumn.getName() + ".array."
18073                                                                                                + dataType.getTypeOfList().getColumnDefList().getColumn(j)
18074                                                                                                                .getColumnName().getColumnNameOnly());
18075                                                                        }
18076                                                                        else {
18077                                                                                columnName.setString(resultColumn.getName() + "."
18078                                                                                                + dataType.getTypeOfList().getColumnDefList().getColumn(j)
18079                                                                                                                .getColumnName().getColumnNameOnly());
18080                                                                        }
18081                                                                        ResultColumn sturctColumn = modelFactory.createResultColumn(resultSet, columnName,
18082                                                                                        true);
18083                                                                        sturctColumn.setStruct(true);
18084                                                                        Function sourceFunction = (Function)createFunction(functionCall);
18085                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18086                                                                        relation.setEffectType(effectType);
18087                                                                        relation.setTarget(new ResultColumnRelationshipElement(sturctColumn));
18088                                                                        if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) {
18089                                                                                for (ResultColumn column : sourceFunction.getColumns()) {
18090                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
18091                                                                                }
18092                                                                        }
18093                                                                }
18094                                                                resultSet.getColumns().remove(resultColumn);
18095                                                        }
18096                                                        return;
18097                                                }
18098                                        }
18099                                }
18100                        }
18101                        
18102                        if(gspObject instanceof TResultColumn) {
18103                                TResultColumn resultColumn = (TResultColumn)gspObject;
18104                                if(resultColumn.getAliasClause()!=null && resultColumn.getAliasClause().getColumns()!=null) {
18105                                        for(TObjectName columnName: resultColumn.getAliasClause().getColumns()) {
18106                                                analyzeFunctionDataFlowRelation(columnName, Arrays.asList(functionCall), effectType, null);
18107                                        }
18108                                        return;
18109                                }
18110                        }
18111                        analyzeFunctionDataFlowRelation(gspObject, Arrays.asList(functionCall), effectType, null);
18112                }
18113        }
18114
18115        private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions,
18116                        EffectType effectType, Process process) {
18117
18118                Object modelObject = modelManager.getModel(gspObject);
18119                if (modelObject == null) {
18120                        if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) {
18121                                modelObject = gspObject;
18122                        }
18123                }
18124
18125                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18126                relation.setEffectType(effectType);
18127                relation.setProcess(process);
18128
18129                if (modelObject instanceof ResultColumn) {
18130                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
18131
18132                } else if (modelObject instanceof TableColumn) {
18133                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
18134
18135                } else {
18136                        throw new UnsupportedOperationException();
18137                }
18138
18139                for (int i = 0; i < functions.size(); i++) {
18140                        TParseTreeNode functionCall = functions.get(i);
18141
18142                        if (functionCall instanceof TFunctionCall) {
18143                                TFunctionCall call = (TFunctionCall) functionCall;
18144                                Procedure callee = modelManager.getProcedureByName(
18145                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call)));
18146                                if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(call))) {
18147                                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(call)));
18148                                        callee = modelManager.getProcedureByName(
18149                                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call)));
18150                                }
18151
18152                                if (callee != null) {
18153                                        String procedureParent = getProcedureParentName(stmtStack.peek());
18154                                        if (procedureParent != null) {
18155                                                Procedure caller = modelManager
18156                                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
18157                                                if (caller != null) {
18158                                                        CallRelationship callRelation = modelFactory.createCallRelation();
18159                                                        callRelation.setCallObject(functionCall);
18160                                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
18161                                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
18162                                                        if (isBuiltInFunctionName(call.getFunctionName()) || isKeyword(call.getFunctionName())) {
18163                                                                callRelation.setBuiltIn(true);
18164                                                        }
18165                                                }
18166                                        }
18167                                        if (callee.getArguments() != null) {
18168                                                for (int j = 0; j < callee.getArguments().size(); j++) {
18169                                                        Argument argument = callee.getArguments().get(j);
18170                                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
18171                                                        if(variable!=null) {
18172                                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
18173                                                                        Transform transform = new Transform();
18174                                                                        transform.setType(Transform.FUNCTION);
18175                                                                        transform.setCode(call);
18176                                                                        variable.getColumns().get(0).setTransform(transform);
18177                                                                }
18178                                                                Process callProcess = modelFactory.createProcess(call);
18179                                                                variable.addProcess(callProcess);
18180                                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), call, j, callProcess);
18181                                                        }
18182                                                }
18183                                        }
18184                                        Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
18185                                                        .getIdentifierNormalTableName(call.getFunctionName().toString()));
18186                                        if (functionTableModelObjs != null) {
18187                                                modelManager.bindModel(call, functionTableModelObjs.iterator().next());
18188                                                for (Object functionTableModelObj : functionTableModelObjs) {
18189                                                        if (functionTableModelObj instanceof ResultSet) {
18190                                                                ResultSet resultSet = (ResultSet) functionTableModelObj;
18191                                                                for (ResultColumn column : resultSet.getColumns()) {
18192                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
18193                                                                }
18194                                                        }
18195                                                }
18196                                        }
18197                                        continue;
18198                                }
18199                        }
18200
18201
18202                        Object functionModel = createFunction(functionCall);
18203                        if (functionModel instanceof Function) {
18204                                Function sourceFunction = (Function)functionModel;
18205                                if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) {
18206                                        for (ResultColumn column : sourceFunction.getColumns()) {
18207                                                relation.addSource(new ResultColumnRelationshipElement(column));
18208                                        }
18209                                }
18210                                else if (functionCall instanceof TFunctionCall) {
18211                                        relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager
18212                                                        .getModel(((TFunctionCall) functionCall).getFunctionName())));
18213                                } else if (functionCall instanceof TCaseExpression) {
18214                                        relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager
18215                                                        .getModel(((TCaseExpression) functionCall).getWhenClauseItemList())));
18216                                }
18217                                
18218                                if (sourceFunction != null && !sourceFunction.getRelationRows().getHoldRelations().isEmpty()) {
18219                                        boolean find = false;
18220                                        if (modelObject instanceof ResultColumn) {
18221                                                ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows();
18222                                                if(targetRelationRows.hasRelation()) {
18223                                                        for(Relationship relationship: targetRelationRows.getHoldRelations()) {
18224                                                                if(relationship.getSources().contains(sourceFunction.getRelationRows())) {
18225                                                                        find = true;
18226                                                                        break;
18227                                                                }
18228                                                        }
18229                                                }
18230                                        }
18231                                        else if (modelObject instanceof TableColumn) {
18232                                                TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows();
18233                                                if(targetRelationRows.hasRelation()) {
18234                                                        for(Relationship relationship: targetRelationRows.getHoldRelations()) {
18235                                                                if(relationship.getSources().contains(sourceFunction.getRelationRows())) {
18236                                                                        find = true;
18237                                                                        break;
18238                                                                }
18239                                                        }
18240                                                }
18241                                        }
18242                                        
18243                                        if (!find) {
18244                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
18245                                                impactRelation.setEffectType(EffectType.select);
18246                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18247                                                                sourceFunction.getRelationRows()));
18248                                                if (modelObject instanceof ResultColumn) {
18249                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18250                                                                        ((ResultColumn) modelObject).getResultSet().getRelationRows()));
18251                                                } else if (modelObject instanceof TableColumn) {
18252                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
18253                                                                        ((TableColumn) modelObject).getTable().getRelationRows()));
18254                                                }
18255                                        }
18256                                }
18257                        } else if (functionModel instanceof Table) {
18258                                TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
18259                                                ((TFunctionCall) functionCall));
18260                                TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
18261                                relation.addSource(element);
18262                        }
18263                }
18264
18265        }
18266
18267        private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys,
18268                        EffectType effectType) {
18269                analyzeSubqueryDataFlowRelation(gspObject, subquerys, effectType, null);
18270        }
18271
18272        private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys,
18273                        EffectType effectType, Process process) {
18274
18275                Object modelObject = modelManager.getModel(gspObject);
18276                if (modelObject == null) {
18277                        if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) {
18278                                modelObject = gspObject;
18279                        }
18280                }
18281
18282                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18283                relation.setEffectType(effectType);
18284                relation.setProcess(process);
18285
18286                if (modelObject instanceof ResultColumn) {
18287                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
18288
18289                } else if (modelObject instanceof TableColumn) {
18290                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
18291
18292                } else {
18293                        throw new UnsupportedOperationException();
18294                }
18295
18296                for (int i = 0; i < subquerys.size(); i++) {
18297                        TSelectSqlStatement subquery = subquerys.get(i);
18298                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
18299                        if (resultSetModel != null && resultSetModel.getColumns() != null) {
18300                                for (ResultColumn column : resultSetModel.getColumns()) {
18301                                        relation.addSource(new ResultColumnRelationshipElement(column));
18302                                }
18303                        }
18304                        
18305                        if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
18306                                boolean find = false;
18307                                if (modelObject instanceof ResultColumn) {
18308                                        ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows();
18309                                        if(targetRelationRows.hasRelation()) {
18310                                                for(Relationship relationship: targetRelationRows.getHoldRelations()) {
18311                                                        if(relationship.getSources().contains(resultSetModel.getRelationRows())) {
18312                                                                find = true;
18313                                                                break;
18314                                                        }
18315                                                }
18316                                        }
18317                                }
18318                                else if (modelObject instanceof TableColumn) {
18319                                        TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows();
18320                                        if(targetRelationRows.hasRelation()) {
18321                                                for(Relationship relationship: targetRelationRows.getHoldRelations()) {
18322                                                        if(relationship.getSources().contains(resultSetModel.getRelationRows())) {
18323                                                                find = true;
18324                                                                break;
18325                                                        }
18326                                                }
18327                                        }
18328                                }
18329                                
18330                                if (!find) {
18331                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
18332                                        impactRelation.setEffectType(EffectType.select);
18333                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18334                                                        resultSetModel.getRelationRows()));
18335                                        if (modelObject instanceof ResultColumn) {
18336                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
18337                                                                ((ResultColumn) modelObject).getResultSet().getRelationRows()));
18338                                        } else if (modelObject instanceof TableColumn) {
18339                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
18340                                                                ((TableColumn) modelObject).getTable().getRelationRows()));
18341                                        }
18342                                }
18343                        }
18344                }
18345
18346        }
18347
18348        private Object createFunction(TParseTreeNode functionCall) {
18349                if (functionCall instanceof TFunctionCall) {
18350                        TFunctionCall functionObj = (TFunctionCall) functionCall;
18351                        if (!isBuiltInFunctionName(functionObj.getFunctionName())) {
18352                                TCustomSqlStatement stmt = stmtStack.peek();
18353                                String procedureParent = getProcedureParentName(stmt);
18354                                if (procedureParent != null) {
18355                                        Procedure procedureCallee = modelManager.getProcedureByName(DlineageUtil
18356                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionObj)));
18357                                        if (procedureCallee != null) {
18358                                                if (procedureParent != null) {
18359                                                        Procedure caller = modelManager
18360                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
18361                                                        if (caller != null) {
18362                                                                CallRelationship callRelation = modelFactory.createCallRelation();
18363                                                                callRelation.setCallObject(functionCall);
18364                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
18365                                                                callRelation.addSource(new ProcedureRelationshipElement(procedureCallee));
18366                                                                if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){
18367                                                                        callRelation.setBuiltIn(true);
18368                                                                }
18369                                                        }
18370                                                }
18371                                                if (procedureCallee.getArguments() != null) {
18372                                                        for (int j = 0; j < procedureCallee.getArguments().size(); j++) {
18373                                                                Argument argument = procedureCallee.getArguments().get(j);
18374                                                                Variable variable = modelFactory.createVariable(procedureCallee, argument.getName(), false);
18375                                                                if(variable!=null) {
18376                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
18377                                                                                Transform transform = new Transform();
18378                                                                                transform.setType(Transform.FUNCTION);
18379                                                                                transform.setCode(functionObj);
18380                                                                                variable.getColumns().get(0).setTransform(transform);
18381                                                                        }
18382                                                                        Process process = modelFactory.createProcess(functionObj);
18383                                                                        variable.addProcess(process);
18384                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionObj, j, process);
18385                                                                }
18386                                                        }
18387                                                }
18388                                        } else {
18389                                                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
18390                                                if (procedureParent != null) {
18391                                                        Procedure caller = modelManager
18392                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
18393                                                        if (caller != null) {
18394                                                                CallRelationship callRelation = modelFactory.createCallRelation();
18395                                                                callRelation.setCallObject(functionCall);
18396                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
18397                                                                callRelation.addSource(new FunctionRelationshipElement(function));
18398                                                                if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){
18399                                                                        callRelation.setBuiltIn(true);
18400                                                                }
18401                                                        }
18402                                                }
18403                                        }
18404                                }
18405                        } else if (isConstantFunction(functionObj.getFunctionName())
18406                                        && (functionObj.getArgs() == null || functionObj.getArgs().size() == 0)) {
18407                                if (option.isShowConstantTable()) {
18408                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
18409                                        modelFactory.createTableColumn(constantTable, functionObj);
18410                                        return constantTable;
18411                                } else {
18412                                        return null;
18413                                }
18414                        }  
18415                        
18416                        if (functionObj.getFunctionType() == EFunctionType.struct_t) {
18417                                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
18418                                TTableFunction tableFunction = (TTableFunction) functionObj;
18419                                if (tableFunction.getFieldValues() != null) {
18420                                        for (int i = 0; i < tableFunction.getFieldValues().size(); i++) {
18421                                                TResultColumn resultColumn = tableFunction.getFieldValues().getResultColumn(i);
18422                                                if (resultColumn.getAliasClause() != null) {
18423                                                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
18424                                                                        resultColumn.getAliasClause().getAliasName());
18425                                                        columnsInExpr visitor = new columnsInExpr();
18426                                                        resultColumn.getExpr().inOrderTraverse(visitor);
18427                                                        List<TObjectName> objectNames = visitor.getObjectNames();
18428                                                        List<TParseTreeNode> functions = visitor.getFunctions();
18429                                                        if (functions != null && !functions.isEmpty()) {
18430                                                                analyzeFunctionDataFlowRelation(column, functions, EffectType.function);
18431                                                        }
18432                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
18433                                                        if (subquerys != null && !subquerys.isEmpty()) {
18434                                                                analyzeSubqueryDataFlowRelation(column, subquerys, EffectType.function);
18435                                                        }
18436                                                        analyzeDataFlowRelation(column, objectNames, EffectType.function, functions);
18437                                                        List<TParseTreeNode> constants = visitor.getConstants();
18438                                                        analyzeConstantDataFlowRelation(column, constants, EffectType.function, functions);
18439                                                } else if (resultColumn.getFieldAttr() != null) {
18440                                                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
18441                                                                        resultColumn.getFieldAttr());
18442                                                        analyzeDataFlowRelation(column, Arrays.asList(resultColumn.getFieldAttr()), EffectType.function, null);
18443                                                } else if (resultColumn.getExpr() != null) {
18444                                                        if (resultColumn.getExpr().getFunctionCall() != null) {
18445                                                                Function resultColumnFunction = (Function) createFunction(
18446                                                                                resultColumn.getExpr().getFunctionCall());
18447                                                                String functionName = getResultSetName(function);
18448                                                                for (int j = 0; j < resultColumnFunction.getColumns().size(); j++) {
18449                                                                        TObjectName columnName = new TObjectName();
18450                                                                        if (resultColumn.getAliasClause() != null) {
18451                                                                                columnName.setString(resultColumn.getAliasClause() + "." + getColumnNameOnly(
18452                                                                                                resultColumnFunction.getColumns().get(j).getName()));
18453                                                                        } else {
18454                                                                                columnName.setString(functionName + "." + getColumnNameOnly(
18455                                                                                                resultColumnFunction.getColumns().get(j).getName()));
18456                                                                        }
18457                                                                        ResultColumn functionResultColumn = modelFactory.createResultColumn(function,
18458                                                                                        columnName);
18459                                                                        DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
18460                                                                        relationship.setTarget(new ResultColumnRelationshipElement(functionResultColumn));
18461                                                                        relationship.addSource(new ResultColumnRelationshipElement(
18462                                                                                        resultColumnFunction.getColumns().get(j)));
18463                                                                }
18464                                                        }
18465                                                        else if (resultColumn.getExpr().getCaseExpression() != null) {
18466                                                                function = modelFactory.createFunction(resultColumn.getExpr().getCaseExpression());
18467                                                                ResultColumn column = modelFactory.createFunctionResultColumn(function,
18468                                                                                ((TCaseExpression) resultColumn.getExpr().getCaseExpression()).getWhenClauseItemList());
18469                                                                analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
18470                                                        }
18471                                                }
18472                                        }
18473                                        return function;
18474                                }
18475                        }
18476                        
18477                        if (functionObj.getFunctionType() == EFunctionType.array_t || functionObj.getFunctionType() == EFunctionType.array_agg_t) {
18478                                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
18479                                if(functionObj.getArgs()!=null) {
18480                                        if(functionObj.getArgs().getExpression(0).getSubQuery()!=null) {
18481                                                TSelectSqlStatement stmt = functionObj.getArgs().getExpression(0).getSubQuery();
18482                                                analyzeSelectStmt(stmt);
18483                                                ResultSet resultset = (ResultSet) modelManager.getModel(stmt);
18484                                                for (int i = 0; i < resultset.getColumns().size(); i++) {
18485                                                        ResultColumn sourceColumn = resultset.getColumns().get(i);
18486                                                        TObjectName columnName = new TObjectName();
18487                                                        columnName.setString(sourceColumn.getName());
18488                                                        ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function,
18489                                                                        columnName);
18490                                                        DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
18491                                                        relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
18492                                                        relationship.addSource(
18493                                                                        new ResultColumnRelationshipElement(sourceColumn));
18494                                                }
18495                                                return function;
18496                                        }
18497                                        else if (functionObj.getArgs().getExpression(0).getExpressionType() == EExpressionType.function_t) {
18498                                                Object functionTableModelObj = createFunction(functionObj.getArgs().getExpression(0).getFunctionCall());
18499                                                if (functionTableModelObj instanceof ResultSet) {
18500                                                        ResultSet resultset = (ResultSet) functionTableModelObj;
18501                                                        for (int i = 0; i < resultset.getColumns().size(); i++) {
18502                                                                ResultColumn sourceColumn = resultset.getColumns().get(i);
18503                                                                TObjectName columnName = new TObjectName();
18504                                                                columnName.setString(sourceColumn.getName());
18505                                                                ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function, columnName);
18506                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
18507                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
18508                                                                relationship.addSource(new ResultColumnRelationshipElement(sourceColumn));
18509                                                        }
18510                                                        return function;
18511                                                }
18512                                        }
18513                                }
18514                        }
18515                        
18516                        Function function = modelFactory.createFunction((TFunctionCall) functionCall);
18517                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
18518                                        ((TFunctionCall) functionCall).getFunctionName());
18519                        if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) {
18520                                // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP
18521                                // COUNT特殊处理,不和参数关联
18522                                if (option.isShowCountTableColumn()) {
18523                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
18524                                }
18525                        } else {
18526                                boolean isCustomFunction = analyzeCustomFunctionCall((TFunctionCall)functionCall);
18527//                              if(!isCustomFunction) 
18528                                {
18529                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
18530                                }
18531                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function));
18532                                if(functionTableModelObjs!=null) {
18533                                        for(Object functionTableModelObj: functionTableModelObjs) {
18534                                                if (functionTableModelObj instanceof ResultSet) {
18535                                                        ResultSet functionTableModel = (ResultSet) functionTableModelObj;
18536                                                        if (functionTableModel.getColumns() != null) {
18537                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
18538                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18539                                                                        relation.setEffectType(EffectType.select);
18540                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18541                                                                        relation.addSource(new ResultColumnRelationshipElement(
18542                                                                                        functionTableModel.getColumns().get(j)));
18543                                                                }
18544                                                        }
18545                                                }
18546                                        }
18547                                }
18548                        }
18549                        return function;
18550                } else if (functionCall instanceof TCaseExpression) {
18551                        Function function = modelFactory.createFunction((TCaseExpression) functionCall);
18552                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
18553                                        ((TCaseExpression) functionCall).getWhenClauseItemList());
18554                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
18555                        return function;
18556                } else if (functionCall instanceof TObjectName) {
18557                        Function function = modelFactory.createFunction((TObjectName) functionCall);
18558                        TObjectName columnName = new TObjectName();
18559                        columnName.setString(functionCall.toString());
18560                        ResultColumn column = modelFactory.createResultColumn(function,
18561                                        columnName);
18562                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
18563                        return function;
18564                }
18565                return null;
18566        }
18567
18568        protected String getIdentifiedFunctionName(Function function) {
18569                return DlineageUtil.getIdentifierNormalFunctionName(function.getFunctionName());
18570        }
18571        
18572        private boolean isConstantFunction(TObjectName functionName) {
18573                boolean result = CONSTANT_BUILTIN_FUNCTIONS.contains(functionName.toString().toUpperCase());
18574                if (result) {
18575                        return true;
18576                }
18577                return false;
18578        }
18579
18580        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TParseTreeNode gspObject) {
18581                List<TExpression> directExpressions = new ArrayList<TExpression>();
18582                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18583                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
18584                if (gspObject instanceof TFunctionCall) {
18585                        TFunctionCall functionCall = (TFunctionCall) gspObject;
18586                        getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
18587                } else if (gspObject instanceof TCaseExpression) {
18588                        TCaseExpression expr = (TCaseExpression) gspObject;
18589                        TExpression inputExpr = expr.getInput_expr();
18590                        if (inputExpr != null) {
18591                                if(option.isShowCaseWhenAsDirect()){
18592                                        directExpressions.add(inputExpr);
18593                                }
18594                                else {
18595                                        conditionExpressions.add(inputExpr);
18596                                }
18597                        }
18598                        TExpression defaultExpr = expr.getElse_expr();
18599                        if (defaultExpr != null) {
18600                                directExpressions.add(defaultExpr);
18601                        }
18602                        TWhenClauseItemList list = expr.getWhenClauseItemList();
18603                        for (int i = 0; i < list.size(); i++) {
18604                                TWhenClauseItem element = list.getWhenClauseItem(i);
18605                                if(option.isShowCaseWhenAsDirect()){
18606                                        directExpressions.add(element.getComparison_expr());
18607                                }
18608                                else {
18609                                        conditionExpressions.add(element.getComparison_expr());
18610                                }
18611                                directExpressions.add(element.getReturn_expr());
18612                        }
18613                }
18614
18615                for (int j = 0; j < directExpressions.size(); j++) {
18616                        columnsInExpr visitor = new columnsInExpr();
18617                        directExpressions.get(j).inOrderTraverse(visitor);
18618
18619                        List<TObjectName> objectNames = visitor.getObjectNames();
18620                        List<TParseTreeNode> functions = visitor.getFunctions();
18621
18622                        if (functions != null && !functions.isEmpty()) {
18623                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
18624                        }
18625
18626                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
18627                        if (subquerys != null && !subquerys.isEmpty()) {
18628                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
18629                        }
18630
18631                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
18632
18633                        List<TParseTreeNode> constants = visitor.getConstants();
18634                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
18635                }
18636
18637                conditionExpressions.addAll(indirectExpressions);
18638                for (int j = 0; j < conditionExpressions.size(); j++) {
18639                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
18640                }
18641        }
18642        
18643        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TCallStatement callStatment, int argumentIndex, Process process) {
18644                List<TExpression> directExpressions = new ArrayList<TExpression>();
18645                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18646                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
18647
18648                getFunctionExpressions(directExpressions, indirectExpressions, callStatment, argumentIndex);
18649
18650                for (int j = 0; j < directExpressions.size(); j++) {
18651                        columnsInExpr visitor = new columnsInExpr();
18652                        directExpressions.get(j).inOrderTraverse(visitor);
18653
18654                        List<TObjectName> objectNames = visitor.getObjectNames();
18655                        List<TParseTreeNode> functions = visitor.getFunctions();
18656
18657                        if (functions != null && !functions.isEmpty()) {
18658                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
18659                        }
18660
18661                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
18662                        if (subquerys != null && !subquerys.isEmpty()) {
18663                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
18664                        }
18665
18666                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
18667                        if (relation != null) {
18668                                relation.setProcess(process);
18669                        }
18670
18671                        List<TParseTreeNode> constants = visitor.getConstants();
18672                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
18673                }
18674
18675                conditionExpressions.addAll(indirectExpressions);
18676                for (int j = 0; j < conditionExpressions.size(); j++) {
18677                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
18678                }
18679        }
18680
18681        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TFunctionCall functionCall, int argumentIndex, Process process) {
18682                List<TExpression> directExpressions = new ArrayList<TExpression>();
18683                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18684                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
18685
18686                getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentIndex);
18687
18688                for (int j = 0; j < directExpressions.size(); j++) {
18689                        columnsInExpr visitor = new columnsInExpr();
18690                        directExpressions.get(j).inOrderTraverse(visitor);
18691
18692                        List<TObjectName> objectNames = visitor.getObjectNames();
18693                        List<TParseTreeNode> functions = visitor.getFunctions();
18694
18695                        if (functions != null && !functions.isEmpty()) {
18696                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
18697                        }
18698
18699                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
18700                        if (subquerys != null && !subquerys.isEmpty()) {
18701                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
18702                        }
18703
18704                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
18705                        if (relation != null) {
18706                                relation.setProcess(process);
18707                        }
18708
18709                        List<TParseTreeNode> constants = visitor.getConstants();
18710                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
18711                }
18712
18713                conditionExpressions.addAll(indirectExpressions);
18714                for (int j = 0; j < conditionExpressions.size(); j++) {
18715                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
18716                }
18717        }
18718
18719        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TMssqlExecute functionCall, String argumentName, int argumentIndex, Process process) {
18720                List<TExpression> directExpressions = new ArrayList<TExpression>();
18721                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18722                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
18723
18724                getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentName, argumentIndex);
18725
18726                for (int j = 0; j < directExpressions.size(); j++) {
18727                        columnsInExpr visitor = new columnsInExpr();
18728                        directExpressions.get(j).inOrderTraverse(visitor);
18729
18730                        List<TObjectName> objectNames = visitor.getObjectNames();
18731                        List<TParseTreeNode> functions = visitor.getFunctions();
18732
18733                        if (functions != null && !functions.isEmpty()) {
18734                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
18735                        }
18736
18737                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
18738                        if (subquerys != null && !subquerys.isEmpty()) {
18739                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
18740                        }
18741
18742                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
18743                        if (relation != null) {
18744                                relation.setProcess(process);
18745                        }
18746
18747                        List<TParseTreeNode> constants = visitor.getConstants();
18748                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
18749                }
18750
18751                conditionExpressions.addAll(indirectExpressions);
18752                for (int j = 0; j < conditionExpressions.size(); j++) {
18753                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
18754                }
18755        }
18756
18757
18758        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
18759                        TFunctionCall functionCall) {
18760                if (functionCall.getArgs() != null) {
18761                        for (int k = 0; k < functionCall.getArgs().size(); k++) {
18762                                TExpression expr = functionCall.getArgs().getExpression(k);
18763                                if(FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(),  functionCall.getArgs().size(), k)) {
18764                                        directExpressions.add(expr);
18765                                }
18766                                if(FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(),  functionCall.getArgs().size(), k)) {
18767                                        indirectExpressions.add(expr);
18768                                }
18769                        }
18770                }
18771                if (functionCall.getXMLElementValueExprList() != null) {
18772                        for (int k = 0; k < functionCall.getXMLElementValueExprList().size(); k++) {
18773                                TExpression expr = functionCall.getXMLElementValueExprList().getResultColumn(k).getExpr();
18774                                directExpressions.add(expr);
18775                        }
18776                }
18777                if (functionCall.getTrimArgument() != null) {
18778                        TTrimArgument args = functionCall.getTrimArgument();
18779                        TExpression expr = args.getStringExpression();
18780                        if (expr != null) {
18781                                directExpressions.add(expr);
18782                        }
18783                        expr = args.getTrimCharacter();
18784                        if (expr != null) {
18785                                directExpressions.add(expr);
18786                        }
18787                }
18788
18789                if (functionCall.getAgainstExpr() != null) {
18790                        directExpressions.add(functionCall.getAgainstExpr());
18791                }
18792//              if (functionCall.getBetweenExpr() != null) {
18793//                      directExpressions.add(functionCall.getBetweenExpr());
18794//              }
18795                if (functionCall.getExpr1() != null) {
18796                        directExpressions.add(functionCall.getExpr1());
18797                }
18798                if (functionCall.getExpr2() != null) {
18799                        directExpressions.add(functionCall.getExpr2());
18800                }
18801                if (functionCall.getExpr3() != null) {
18802                        directExpressions.add(functionCall.getExpr3());
18803                }
18804                if (functionCall.getParameter() != null) {
18805                        directExpressions.add(functionCall.getParameter());
18806                }
18807                if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getPartitionClause() != null) {
18808                        TExpressionList args = functionCall.getWindowDef().getPartitionClause().getExpressionList();
18809                        if (args != null) {
18810                                for (int k = 0; k < args.size(); k++) {
18811                                        TExpression expr = args.getExpression(k);
18812                                        if (expr != null) {
18813                                                indirectExpressions.add(expr);
18814                                        }
18815                                }
18816                        }
18817                }
18818                if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getOrderBy() != null) {
18819                        TOrderByItemList orderByList = functionCall.getWindowDef().getOrderBy().getItems();
18820                        for (int i = 0; i < orderByList.size(); i++) {
18821                                TOrderByItem element = orderByList.getOrderByItem(i);
18822                                TExpression expression = element.getSortKey();
18823                                indirectExpressions.add(expression);
18824                        }
18825                }
18826                if (functionCall.getWithinGroup() != null && functionCall.getWithinGroup().getOrderBy() != null) {
18827                        TOrderByItemList orderByList = functionCall.getWithinGroup().getOrderBy().getItems();
18828                        for (int i = 0; i < orderByList.size(); i++) {
18829                                TOrderByItem element = orderByList.getOrderByItem(i);
18830                                TExpression expression = element.getSortKey();
18831                                indirectExpressions.add(expression);
18832                        }
18833                }
18834                if (functionCall.getCallTarget() != null) {
18835                        directExpressions.add(functionCall.getCallTarget().getExpr());
18836                }
18837                if (functionCall.getFieldValues() != null) {
18838                        for (int k = 0; k < functionCall.getFieldValues().size(); k++) {
18839                                TExpression expr = functionCall.getFieldValues().getResultColumn(k).getExpr();
18840                                directExpressions.add(expr);
18841                        }
18842                }
18843                if (functionCall instanceof TJsonObjectFunction) {
18844                        TJsonObjectFunction jsonObject = (TJsonObjectFunction)functionCall;
18845                        for (int k = 0; k < jsonObject.getKeyValues().size(); k++) {
18846                                TExpression expr = jsonObject.getKeyValues().get(k).getValue();
18847                                directExpressions.add(expr);
18848                        }
18849                }
18850        }
18851
18852        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
18853                                                                                TFunctionCall functionCall, int argumentIndex) {
18854                if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) {
18855                        TExpression expr = functionCall.getArgs().getExpression(argumentIndex);
18856                        if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) {
18857                                directExpressions.add(expr);
18858                        }
18859                        if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) {
18860                                indirectExpressions.add(expr);
18861                        }
18862                }
18863        }
18864        
18865        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
18866                        TCallStatement functionCall, int argumentIndex) {
18867                if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) {
18868                        TExpression expr = functionCall.getArgs().getExpression(argumentIndex);
18869                        if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getRoutineName().toString(),
18870                                        functionCall.getArgs().size(), argumentIndex)) {
18871                                directExpressions.add(expr);
18872                        }
18873                        if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getRoutineName().toString(),
18874                                        functionCall.getArgs().size(), argumentIndex)) {
18875                                indirectExpressions.add(expr);
18876                        }
18877                }
18878        }
18879
18880        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
18881                                                                                TMssqlExecute functionCall, String argumentName, int argumentIndex) {
18882                if (functionCall.getParameters() != null) {
18883                        for (int i = 0; i < functionCall.getParameters().size(); i++) {
18884                                TExecParameter param = functionCall.getParameters().getExecParameter(i);
18885                                if (param.getParameterName() != null) {
18886                                        if (DlineageUtil.compareColumnIdentifier(param.getParameterName().toString(), argumentName)) {
18887                                                TExpression expr = param.getParameterValue();
18888                                                directExpressions.add(expr);
18889                                        }
18890                                } else if (i == argumentIndex) {
18891                                        TExpression expr = param.getParameterValue();
18892                                        directExpressions.add(expr);
18893                                }
18894                        }
18895                }
18896        }
18897
18898        private void analyzeJoin(TJoin join, EffectType effectType) {
18899                if (join.getJoinItems() != null) {
18900                        for (int j = 0; j < join.getJoinItems().size(); j++) {
18901                                TJoinItem joinItem = join.getJoinItems().getJoinItem(j);
18902                                TExpression expr = joinItem.getOnCondition();
18903                                if (expr != null) {
18904                                        analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on, effectType);
18905                                }
18906                        }
18907                }
18908
18909                if (join.getJoin() != null) {
18910                        analyzeJoin(join.getJoin(), effectType);
18911                }
18912        }
18913
18914        private TSelectSqlStatement getParentSetSelectStmt(TSelectSqlStatement stmt) {
18915                TCustomSqlStatement parent = stmt.getParentStmt();
18916                if (parent == null)
18917                        return null;
18918                if (parent.getStatements() != null) {
18919                        for (int i = 0; i < parent.getStatements().size(); i++) {
18920                                TCustomSqlStatement temp = parent.getStatements().get(i);
18921                                if (temp instanceof TSelectSqlStatement) {
18922                                        TSelectSqlStatement select = (TSelectSqlStatement) temp;
18923                                        if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt)
18924                                                return select;
18925                                }
18926                        }
18927                }
18928                if (parent instanceof TSelectSqlStatement) {
18929                        TSelectSqlStatement select = (TSelectSqlStatement) parent;
18930                        if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt)
18931                                return select;
18932                }
18933                return null;
18934        }
18935
18936        private void createSelectSetResultColumns(SelectSetResultSet resultSet, TSelectSqlStatement stmt) {
18937                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
18938                        createSelectSetResultColumns(resultSet, stmt.getLeftStmt());
18939                } else {
18940                        TResultColumnList columnList = stmt.getResultColumnList();
18941                        ResultSet subqueryResultSet = (ResultSet) modelManager.getModel(columnList);
18942                        if(subqueryResultSet!=null && subqueryResultSet.isDetermined()) {
18943                                for (int j = 0; j < subqueryResultSet.getColumns().size(); j++) {
18944                                        ResultColumn tableColumn = subqueryResultSet.getColumns().get(j);
18945                                        if (tableColumn.getRefColumnName() != null) {
18946                                                TObjectName columnName = new TObjectName();
18947                                                columnName.setString(tableColumn.getRefColumnName());
18948                                                modelFactory.createResultColumn(
18949                                                                resultSet, columnName);
18950                                        } else {
18951                                                TObjectName columnName = new TObjectName();
18952                                                columnName.setString(tableColumn.getName());
18953                                                modelFactory.createResultColumn(
18954                                                                resultSet, columnName);
18955                                        }
18956                                }
18957                                resultSet.setDetermined(true);
18958                                return;
18959                        }
18960                        
18961                        boolean isDetermined = true;
18962                        for (int i = 0; i < columnList.size(); i++) {
18963                                TResultColumn column = columnList.getResultColumn(i);
18964                                
18965                                if ("*".equals(column.getColumnNameOnly())) {
18966                                        TObjectName columnObject = column.getFieldAttr();
18967                                        TTable sourceTable = columnObject.getSourceTable();
18968                                        if (sourceTable != null) {
18969                                                Object tableModel = modelManager.getModel(sourceTable);
18970                                                if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
18971                                                        Table table = (Table) tableModel;
18972                                                        for (int j = 0; j < table.getColumns().size(); j++) {
18973                                                                TableColumn tableColumn = table.getColumns().get(j);
18974                                                                if (column.getExceptColumnList() != null) {
18975                                                                        boolean except = false;
18976                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
18977                                                                                if (getColumnName(objectName.toString())
18978                                                                                                .equals(getColumnName(tableColumn.getName()))) {
18979                                                                                        except = true;
18980                                                                                        break;
18981                                                                                }
18982                                                                        }
18983                                                                        if (!except && tableColumn.isStruct()) {
18984                                                                                List<String> names = SQLUtil
18985                                                                                                .parseNames(tableColumn.getName());
18986                                                                                for (String name : names) {
18987                                                                                        for (TObjectName objectName : column
18988                                                                                                        .getExceptColumnList()) {
18989                                                                                                if (getColumnName(objectName.toString())
18990                                                                                                                .equals(getColumnName(name))) {
18991                                                                                                        except = true;
18992                                                                                                        break;
18993                                                                                                }
18994                                                                                        }
18995                                                                                        if (except) {
18996                                                                                                break;
18997                                                                                        }
18998                                                                                }
18999                                                                        }
19000                                                                        if (except) {
19001                                                                                continue;
19002                                                                        }
19003                                                                }
19004                                                                TObjectName columnName = new TObjectName();
19005                                                                columnName.setString(tableColumn.getName());
19006                                                                ResultColumn resultColumn = modelFactory.createResultColumn(
19007                                                                                resultSet, columnName);
19008                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19009                                                                relation.setEffectType(EffectType.select);
19010                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19011                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
19012                                                        }
19013                                                        continue;
19014                                                } else if (tableModel instanceof ResultSet
19015                                                                && ((ResultSet) tableModel).isDetermined()) {
19016                                                        ResultSet table = (ResultSet) tableModel;
19017                                                        for (int j = 0; j < table.getColumns().size(); j++) {
19018                                                                ResultColumn tableColumn = table.getColumns().get(j);
19019                                                                if (column.getExceptColumnList() != null) {
19020                                                                        boolean except = false;
19021                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
19022                                                                                if (getColumnName(objectName.toString())
19023                                                                                                .equals(getColumnName(tableColumn.getName()))) {
19024                                                                                        except = true;
19025                                                                                        break;
19026                                                                                }
19027                                                                        }
19028                                                                        if (!except && tableColumn.isStruct()) {
19029                                                                                List<String> names = SQLUtil
19030                                                                                                .parseNames(tableColumn.getName());
19031                                                                                for (String name : names) {
19032                                                                                        for (TObjectName objectName : column
19033                                                                                                        .getExceptColumnList()) {
19034                                                                                                if (getColumnName(objectName.toString())
19035                                                                                                                .equals(getColumnName(name))) {
19036                                                                                                        except = true;
19037                                                                                                        break;
19038                                                                                                }
19039                                                                                        }
19040                                                                                        if (except) {
19041                                                                                                break;
19042                                                                                        }
19043                                                                                }
19044                                                                        }
19045                                                                        if (except) {
19046                                                                                continue;
19047                                                                        }
19048                                                                }
19049                                                                if (tableColumn.getRefColumnName() != null) {
19050                                                                        TObjectName columnName = new TObjectName();
19051                                                                        columnName.setString(tableColumn.getRefColumnName());
19052                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(
19053                                                                                        resultSet, columnName);
19054                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19055                                                                        relation.setEffectType(EffectType.select);
19056                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19057                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19058                                                                } else {
19059                                                                        TObjectName columnName = new TObjectName();
19060                                                                        columnName.setString(tableColumn.getName());
19061                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(
19062                                                                                        resultSet, columnName);
19063                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19064                                                                        relation.setEffectType(EffectType.select);
19065                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19066                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19067                                                                }
19068                                                        }
19069                                                        continue;
19070                                                }
19071                                                else {
19072                                                        isDetermined = false;
19073                                                }
19074                                        }
19075                                }
19076                                        
19077                                ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
19078
19079                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
19080                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
19081                                        if (columnObject.getFieldAttr() != null) {
19082                                                if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
19083                                                        TObjectName fieldAttr = columnObject.getFieldAttr();
19084                                                        TTable sourceTable = fieldAttr.getSourceTable();
19085                                                        if (fieldAttr.getTableToken() != null && sourceTable != null) {
19086                                                                TObjectName[] columns = modelManager.getTableColumns(sourceTable);
19087                                                                for (int j = 0; j < columns.length; j++) {
19088                                                                        TObjectName columnName = columns[j];
19089                                                                        if (columnName == null) {
19090                                                                                continue;
19091                                                                        }
19092                                                                        if ("*".equals(getColumnName(columnName))) {
19093                                                                                continue;
19094                                                                        }
19095                                                                        resultColumn.bindStarLinkColumn(columnName);
19096                                                                }
19097
19098                                                                if (modelManager.getModel(sourceTable) instanceof Table) {
19099                                                                        Table tableModel = (Table) modelManager.getModel(sourceTable);
19100                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19101                                                                                for (int z = 0; z < tableModel.getColumns().size(); z++) {
19102                                                                                        if ("*".equals(
19103                                                                                                        getColumnName(tableModel.getColumns().get(z).getColumnObject()))) {
19104                                                                                                continue;
19105                                                                                        }
19106                                                                                        resultColumn.bindStarLinkColumn(
19107                                                                                                        tableModel.getColumns().get(z).getColumnObject());
19108                                                                                }
19109                                                                        }
19110                                                                } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
19111                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
19112                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19113                                                                                for (ResultColumn item : tableModel.getColumns()) {
19114                                                                                        if (item.hasStarLinkColumn()) {
19115                                                                                                for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
19116                                                                                                        if ("*".equals(getColumnName(starLinkColumn))) {
19117                                                                                                                continue;
19118                                                                                                        }
19119                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
19120                                                                                                }
19121                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
19122                                                                                                TObjectName starLinkColumn = (TObjectName) item.getColumnObject();
19123                                                                                                if ("*".equals(getColumnName(starLinkColumn))) {
19124                                                                                                        continue;
19125                                                                                                }
19126                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
19127                                                                                        }
19128                                                                                }
19129                                                                        }
19130                                                                }
19131
19132                                                        } else {
19133                                                                TTableList tables = stmt.getTables();
19134                                                                for (int k = 0; k < tables.size(); k++) {
19135                                                                        TTable tableElement = tables.getTable(k);
19136                                                                        TObjectName[] columns = modelManager.getTableColumns(tableElement);
19137                                                                        for (int j = 0; j < columns.length; j++) {
19138                                                                                TObjectName columnName = columns[j];
19139                                                                                if (columnName == null) {
19140                                                                                        continue;
19141                                                                                }
19142                                                                                if ("*".equals(getColumnName(columnName))) {
19143                                                                                        if (modelManager.getModel(tableElement) instanceof Table) {
19144                                                                                                Table tableModel = (Table) modelManager.getModel(tableElement);
19145                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19146                                                                                                        for (int z = 0; z < tableModel.getColumns().size(); z++) {
19147                                                                                                                resultColumn.bindStarLinkColumn(
19148                                                                                                                                tableModel.getColumns().get(z).getColumnObject());
19149                                                                                                        }
19150                                                                                                }
19151                                                                                        } else if (modelManager.getModel(tableElement) instanceof QueryTable) {
19152                                                                                                QueryTable tableModel = (QueryTable) modelManager
19153                                                                                                                .getModel(tableElement);
19154                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
19155                                                                                                        for (ResultColumn item : tableModel.getColumns()) {
19156                                                                                                                if (item.hasStarLinkColumn()) {
19157                                                                                                                        for (TObjectName starLinkColumn : item
19158                                                                                                                                        .getStarLinkColumnList()) {
19159                                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
19160                                                                                                                        }
19161                                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
19162                                                                                                                        resultColumn.bindStarLinkColumn(
19163                                                                                                                                        (TObjectName) item.getColumnObject());
19164                                                                                                                }
19165                                                                                                        }
19166                                                                                                }
19167                                                                                        }
19168                                                                                        continue;
19169                                                                                }
19170                                                                                resultColumn.bindStarLinkColumn(columnName);
19171                                                                        }
19172                                                                }
19173                                                        }
19174                                                }
19175                                        }
19176                                }
19177                                
19178                                resultSet.setDetermined(isDetermined);
19179                        }
19180                }
19181        }
19182
19183        private void analyzeResultColumn(TResultColumn column, EffectType effectType) {
19184                TExpression expression = column.getExpr();
19185                if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
19186                        expression = expression.getRightOperand();
19187                }
19188
19189                if (expression.getExpressionType() == EExpressionType.array_t) {
19190                        if (expression.getExprList() != null) {
19191                                for (TExpression expr : expression.getExprList()) {
19192                                        columnsInExpr visitor = new columnsInExpr();
19193                                        expr.inOrderTraverse(visitor);
19194                                        List<TObjectName> objectNames = visitor.getObjectNames();
19195
19196                                        List<TParseTreeNode> functions = visitor.getFunctions();
19197
19198                                        if (functions != null && !functions.isEmpty()) {
19199                                                analyzeFunctionDataFlowRelation(column, functions, effectType);
19200                                        }
19201
19202                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19203                                        if (subquerys != null && !subquerys.isEmpty()) {
19204                                                analyzeSubqueryDataFlowRelation(column, subquerys, effectType);
19205                                        }
19206
19207                                        analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions);
19208
19209                                        List<TParseTreeNode> constants = visitor.getConstants();
19210                                        Object columnObject = modelManager.getModel(column);
19211                                        analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions);
19212
19213                                        analyzeRecordSetRelation(functions, effectType);
19214                                        // analyzeResultColumnImpact( column, effectType, functions);
19215                                }
19216                        }
19217                        else {
19218                                List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
19219                                TConstant constant = new TConstant();
19220                                constant.setString(expression.toString());
19221                                constants.add(constant);
19222                                Object columnObject = modelManager.getModel(column);
19223                                analyzeConstantDataFlowRelation(columnObject, constants, effectType, null);
19224                        }
19225                } else {
19226                        columnsInExpr visitor = new columnsInExpr();
19227                        expression.inOrderTraverse(visitor);
19228                        List<TObjectName> objectNames = visitor.getObjectNames();
19229
19230                        List<TParseTreeNode> functions = visitor.getFunctions();
19231
19232                        if (functions != null && !functions.isEmpty()) {
19233                                analyzeFunctionDataFlowRelation(column, functions, effectType);
19234                        }
19235
19236                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19237                        if (subquerys != null && !subquerys.isEmpty()) {
19238                                analyzeSubqueryDataFlowRelation(column, subquerys, effectType);
19239                        }
19240
19241                        analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions);
19242
19243                        List<TParseTreeNode> constants = visitor.getConstants();
19244                        Object columnObject = modelManager.getModel(column);
19245                        analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions);
19246
19247                        analyzeRecordSetRelation(functions, effectType);
19248                        // analyzeResultColumnImpact( column, effectType, functions);
19249                }
19250        }
19251        
19252        
19253        private void analyzeValueColumn(Object object, TResultColumn column, EffectType effectType) {
19254                TExpression expression = column.getExpr();
19255                if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
19256                        expression = expression.getRightOperand();
19257                }
19258
19259                if (expression.getExpressionType() == EExpressionType.array_t) {
19260                        if (expression.getExprList() != null) {
19261                                for (TExpression expr : expression.getExprList()) {
19262                                        columnsInExpr visitor = new columnsInExpr();
19263                                        expr.inOrderTraverse(visitor);
19264                                        List<TObjectName> objectNames = visitor.getObjectNames();
19265                                        analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null);
19266                                        List<TParseTreeNode> constants = visitor.getConstants();
19267                                        analyzeConstantDataFlowRelation(object, constants, effectType, null);
19268                                }
19269                        }
19270                        else {
19271                                List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
19272                                TConstant constant = new TConstant();
19273                                constant.setString(expression.toString());
19274                                constants.add(constant);
19275                                Object columnObject = modelManager.getModel(column);
19276                                analyzeConstantDataFlowRelation(object, constants, effectType, null);
19277                        }
19278                } else {
19279                        columnsInExpr visitor = new columnsInExpr();
19280                        expression.inOrderTraverse(visitor);
19281                        List<TObjectName> objectNames = visitor.getObjectNames();
19282                        analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null);
19283                        List<TParseTreeNode> constants = visitor.getConstants();
19284                        analyzeConstantDataFlowRelation(object, constants, effectType, null);           }
19285        }
19286
19287        private void analyzeTableColumn(TableColumn tableColumn, TFunctionCall functionCall, EffectType effectType) {
19288                List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>();
19289                functions.add(functionCall);
19290
19291                if (functions != null && !functions.isEmpty()) {
19292                        analyzeFunctionDataFlowRelation(tableColumn, functions, effectType);
19293                }
19294
19295                analyzeRecordSetRelation(functions, effectType);
19296        }
19297
19298        private void analyzeRecordSetRelation(List<TParseTreeNode> functions, EffectType effectType) {
19299                if (functions == null || functions.size() == 0)
19300                        return;
19301
19302                List<TFunctionCall> aggregateFunctions = new ArrayList<TFunctionCall>();
19303                for (TParseTreeNode function : functions) {
19304                        if (function instanceof TFunctionCall && isAggregateFunction((TFunctionCall) function)) {
19305                                aggregateFunctions.add((TFunctionCall) function);
19306                        }
19307                }
19308
19309                if (aggregateFunctions.size() == 0)
19310                        return;
19311
19312                for (int i = 0; i < aggregateFunctions.size(); i++) {
19313                        TFunctionCall function = aggregateFunctions.get(i);
19314
19315                        TCustomSqlStatement stmt = stmtStack.peek();
19316                        if (stmt instanceof TSelectSqlStatement) {
19317                                TSelectSqlStatement select = (TSelectSqlStatement) stmt;
19318                                if (select.getGroupByClause() != null) {
19319                                        TGroupByItemList groupByList = select.getGroupByClause().getItems();
19320                                        for (int j = 0; j < groupByList.size(); j++) {
19321                                                TGroupByItem groupBy = groupByList.getGroupByItem(j);
19322                                                TExpression expr = groupBy.getExpr();
19323                                                analyzeAggregate(function, expr);
19324                                        }
19325
19326                                        if (select.getGroupByClause().getHavingClause() != null) {
19327                                                analyzeAggregate(function, select.getGroupByClause().getHavingClause());
19328                                        }
19329                                        // if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString()))
19330                                        {
19331                                                analyzeAggregate(function, null);
19332                                        }
19333                                } else {
19334                                        analyzeAggregate(function, null);
19335                                }
19336                        }
19337                }
19338        }
19339
19340        private void analyzeDataFlowRelation(TParseTreeNode gspObject, List<TObjectName> objectNames,
19341                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions) {
19342                Object columnObject = modelManager.getModel(gspObject);
19343                analyzeDataFlowRelation(columnObject, objectNames, exceptColumnList, effectType, functions, null);
19344        }
19345
19346        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType,
19347                        List<TParseTreeNode> functions) {
19348                return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, null);
19349        }
19350        
19351        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType,
19352                        List<TParseTreeNode> functions, Process process) {
19353                return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, process);
19354        }
19355
19356        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames,
19357                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process) {
19358                return analyzeDataFlowRelation(modelObject, objectNames, exceptColumnList, effectType, functions, process, null);
19359        }
19360        
19361        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames,
19362                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process, Integer valueIndex) {
19363                if (objectNames == null || objectNames.size() == 0)
19364                        return null;
19365
19366                boolean isStar = false;
19367                boolean showStar = false;
19368
19369                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19370                relation.setEffectType(effectType);
19371                relation.setProcess(process);
19372
19373                if (functions != null && !functions.isEmpty()) {
19374                        relation.setFunction(getFunctionName(functions.get(0)));
19375                }
19376
19377                int columnIndex = -1;
19378
19379                boolean isOut = false;
19380
19381                if (modelObject instanceof ResultColumn) {
19382                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
19383
19384                        if ("*".equals(((ResultColumn) modelObject).getName())) {
19385                                isStar = true;
19386                                showStar = ((ResultColumn) modelObject).isShowStar();
19387                        }
19388
19389                        if (((ResultColumn) modelObject).getResultSet() != null) {
19390                                columnIndex = ((ResultColumn) modelObject).getResultSet().getColumns().indexOf(modelObject);
19391                        }
19392                } else if (modelObject instanceof TableColumn) {
19393                        Table table  = ((TableColumn) modelObject).getTable();
19394                        if(table.getSubType() == SubType.out && isNotInProcedure(table)){
19395                                isOut = true;
19396                                relation.addSource(new TableColumnRelationshipElement((TableColumn) modelObject));
19397                        }
19398                        else {
19399                                relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
19400                        }
19401
19402                        if ("*".equals(((TableColumn) modelObject).getName())) {
19403                                isStar = true;
19404                        }
19405
19406                        if (((TableColumn) modelObject).getTable() != null) {
19407                                columnIndex = ((TableColumn) modelObject).getTable().getColumns().indexOf(modelObject);
19408                        }
19409                } else {
19410                        throw new UnsupportedOperationException();
19411                }
19412
19413                for (int i = 0; i < objectNames.size(); i++) {
19414                        TObjectName columnName = objectNames.get(i);
19415                        if (columnName.toString().indexOf(".") == -1 && isConstant(columnName)) {
19416                                boolean isConstant = true;
19417                                if (columnName.getSourceTable() != null) {
19418                                        Table tableModel = modelManager.getTableByName(
19419                                                        DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString()));
19420                                        if (tableModel != null && tableModel.getColumns() != null) {
19421                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
19422                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
19423                                                                        getColumnName(tableModel.getColumns().get(j).getName()))) {
19424                                                                isConstant = false;
19425                                                                break;
19426                                                        }
19427                                                }
19428                                        }
19429                                }
19430
19431                                if (isConstant) {
19432                                        if (option.isShowConstantTable()) {
19433                                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
19434                                                TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false);
19435                                                if(tableColumn!=null) {
19436                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
19437                                                }
19438                                        }
19439                                        continue;
19440                                }
19441                        }
19442                        if (columnName.getDbObjectType() == EDbObjectType.variable) {
19443                                boolean find = false;
19444                                List<String> segments = SQLUtil.parseNames(columnName.toString());
19445                                if (segments.size() == 1) {
19446                                        Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString()));
19447                                        if (variable != null) {
19448                                                TableColumn columnModel = variable.getColumns().get(0);
19449                                                if(variable.getColumns().size()>0){
19450                                                        TableColumn matchColumn = matchColumn(variable.getColumns(), columnName);
19451                                                        if(matchColumn!=null){
19452                                                                columnModel = matchColumn;
19453                                                        }
19454                                                }
19455                                                if(isOut){
19456                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
19457                                                }
19458                                                else {
19459                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
19460                                                }
19461                                                find = true;
19462                                        } else {
19463                                                if (columnName.toString().matches("\\$\\d+")) {
19464                                                        TCustomSqlStatement stmt = stmtStack.peek();
19465                                                        Procedure procedure = modelManager
19466                                                                        .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt)));
19467                                                        if(procedure!=null) {
19468                                                                Variable cursorVariable = modelFactory.createVariable(procedure.getArguments().get(Integer.valueOf(columnName.toString().replace("$", "")) - 1).getName());
19469                                                                if (isOut) {
19470                                                                        relation.setTarget(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
19471                                                                } else {
19472                                                                        relation.addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
19473                                                                }
19474                                                        }
19475                                                } else {
19476                                                        Variable cursorVariable = modelFactory.createVariable(columnName);
19477                                                        cursorVariable.setCreateTable(true);
19478                                                        cursorVariable.setSubType(SubType.record);
19479                                                        TableColumn variableProperty = null;
19480                                                        if(cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
19481                                variableProperty = modelFactory.createTableColumn(cursorVariable, columnName,
19482                                        true);
19483                            }
19484                                                        else{
19485                                                                variableProperty = cursorVariable.getColumns().get(0);
19486                                                        }
19487                                                        if (isOut) {
19488                                                                relation.setTarget(new TableColumnRelationshipElement(variableProperty));
19489                                                        } else {
19490                                                                relation.addSource(new TableColumnRelationshipElement(variableProperty));
19491                                                        }
19492                                                }
19493                                                find = true;
19494                                        }
19495                                } else if (option.getVendor() == EDbVendor.dbvoracle) {
19496                                        String name = columnName.toString();
19497                                        Variable cursorVariable = modelFactory
19498                                                        .createVariable(DlineageUtil.getTableFullName(name.substring(0, name.lastIndexOf("."))));
19499
19500                                        TObjectName variableColumnName = new TObjectName();
19501                                        variableColumnName.setString(segments.get(segments.size() - 1));
19502
19503                                        if (cursorVariable.getColumns() != null) {
19504                                                for (int j = 0; j < cursorVariable.getColumns().size(); j++) {
19505                                                        if (getColumnName(variableColumnName)
19506                                                                        .equals(getColumnName(cursorVariable.getColumns().get(j).getColumnObject()))) {
19507                                                                TableColumn columnModel = cursorVariable.getColumns().get(j);
19508                                                                if (isOut) {
19509                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
19510                                                                } else {
19511                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
19512                                                                }
19513                                                                find = true;
19514                                                        }
19515                                                }
19516                                        }
19517
19518                                        if (!find) {
19519                                                TableColumn variableColumn = new TableColumn(cursorVariable, variableColumnName);
19520                                                cursorVariable.addColumn(variableColumn);
19521                                                if (isOut) {
19522                                                        relation.setTarget(new TableColumnRelationshipElement(variableColumn));
19523                                                } else {
19524                                                        relation.addSource(new TableColumnRelationshipElement(variableColumn));
19525                                                }
19526                                        }
19527                                } else {
19528                                        Table variable = modelManager
19529                                                        .getTableByName(DlineageUtil.getTableFullName(segments.get(segments.size() - 2)));
19530                                        if (variable != null) {
19531                                                for (int j = 0; j < variable.getColumns().size(); j++) {
19532                                                        if (getColumnName(columnName)
19533                                                                        .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) {
19534                                                                TableColumn columnModel = variable.getColumns().get(j);
19535                                                                if (isOut) {
19536                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
19537                                                                } else {
19538                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
19539                                                                }
19540                                                                find = true;
19541                                                        }
19542                                                }
19543                                        }
19544                                }
19545                                if (!find) {
19546                                        TCustomSqlStatement stmt = stmtStack.peek();
19547                                        if (getProcedureParentName(stmt) != null) {
19548                                                Procedure procedure = modelManager
19549                                                                .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt)));
19550                                                if (procedure != null && procedure.getArguments() != null) {
19551                                                        for (Argument argument : procedure.getArguments()) {
19552                                                                if (DlineageUtil.getTableFullName(argument.getName())
19553                                                                                .equals(DlineageUtil.getTableFullName(columnName.toString()))) {
19554                                                                        relation.addSource(new ArgumentRelationshipElement(argument));
19555                                                                }
19556                                                        }
19557                                                }
19558                                        }
19559                                }
19560                                continue;
19561                        }
19562                        
19563                        if("NEXTVAL".equalsIgnoreCase(columnName.getColumnNameOnly()) && option.getVendor() == EDbVendor.dbvoracle){
19564                                List<String> segments = SQLUtil.parseNames(columnName.toString());
19565                                segments.remove(segments.size()-1);
19566                                Table table = modelFactory.createTableByName(SQLUtil.mergeSegments(segments, 0), true);
19567                                table.setSequence(true);
19568                                TableColumn seqCursor = modelFactory.createTableColumn(table, columnName, true);
19569                                relation.addSource(new TableColumnRelationshipElement(seqCursor));
19570                                continue;
19571                        }
19572
19573                        {
19574                                if (columnName.getSourceTable() != null) {
19575
19576                                }
19577                                else {
19578                                        Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString()));
19579                                        if (variable == null) {
19580                                                variable = modelManager
19581                                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getTableString()));
19582                                                if (variable != null && variable.isCursor()) {
19583                                                        TableColumn variableColumn = modelFactory.createInsertTableColumn(variable, columnName);
19584                                                        if (variableColumn != null) {
19585                                                                if(isOut){
19586                                                                        relation.setTarget(new TableColumnRelationshipElement(variableColumn));
19587                                                                }
19588                                                                else {
19589                                                                        relation.addSource(new TableColumnRelationshipElement(variableColumn));
19590                                                                }
19591                                                        } else {
19592                                                                if(isOut){
19593                                                                        relation.setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0)));
19594                                                                }
19595                                                                else {
19596                                                                        relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0)));
19597                                                                }
19598                                                        }
19599                                                        continue;
19600                                                }
19601                                        } else if (variable.isVariable() || variable.isCursor()) {
19602                                                TableColumn columnModel = variable.getColumns().get(0);
19603                                                if (valueIndex != null) {
19604                                                        if(isOut){
19605                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel, valueIndex));
19606                                                        }
19607                                                        else {
19608                                                                relation.addSource(new TableColumnRelationshipElement(columnModel, valueIndex));
19609                                                        }
19610                                                } else {
19611                                                        if(isOut){
19612                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel));
19613                                                        }
19614                                                        else {
19615                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
19616                                                        }
19617                                                }
19618                                                continue;
19619                                        }
19620                                }
19621                        }
19622                        
19623                        if (columnName.getColumnNameOnly().startsWith("@")
19624                                        && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
19625                                continue;
19626                        }
19627
19628                        if (columnName.getColumnNameOnly().startsWith(":")
19629                                        && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
19630                                Table variable = modelManager
19631                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getColumnNameOnly().replace(":", "")));
19632                                if (variable != null) {
19633                                        for (int j = 0; j < variable.getColumns().size(); j++) {
19634                                                if (getColumnName(columnName).replace(":", "")
19635                                                                .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) {
19636                                                        TableColumn columnModel = variable.getColumns().get(j);
19637                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
19638                                                }
19639                                        }
19640                                }
19641                                continue;
19642                        }
19643
19644                        boolean linkedFirstTable = false;
19645                        
19646                        TCustomSqlStatement stmt = stmtStack.peek();
19647                        TTableList tableList = stmt.tables;
19648                        if ((tableList == null || tableList.size() == 0) && (hiveFromTables != null && hiveFromTables.size() > 0)) {
19649                                tableList = hiveFromTables;
19650                        }
19651
19652                        List<TTable> tables = new ArrayList<TTable>();
19653                        {
19654                                TTable table = columnName.getSourceTable();
19655
19656                                // 针对CursorVariable特殊处理
19657                                if (columnName.getTableToken() != null) {
19658
19659                                        Table tableModel = null;
19660                                        if (table != null && modelManager.getModel(table) instanceof Table) {
19661                                                tableModel = (Table) modelManager.getModel(table);
19662                                        }
19663
19664                                        if (tableModel == null) {
19665                                                tableModel = modelManager
19666                                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getTableToken().toString()));
19667                                        }
19668
19669                                        if (tableModel == null) {
19670                                                TCustomSqlStatement currentStmt = ModelBindingManager.getGlobalStmtStack().peek();
19671                                                String procedureName = DlineageUtil.getProcedureParentName(currentStmt);
19672                                                String variableString = columnName.getTableToken().toString();
19673                                                if (variableString.startsWith(":")) {
19674                                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
19675                                                }
19676                                                if (!SQLUtil.isEmpty(procedureName)) {
19677                                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
19678                                                }
19679
19680                                                if (modelManager
19681                                                                .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
19682                                                        tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
19683                                                }
19684                                        }
19685
19686                                        if (tableModel != null) {
19687
19688                                                if (table == null) {
19689                                                        table = tableModel.getTableObject();
19690                                                }
19691
19692                                                if (tableModel.isVariable()) {
19693                                                        if (!isStar && "*".equals(getColumnName(columnName))) {
19694                                                                TObjectName[] columns = modelManager.getTableColumns(table);
19695                                                                for (int j = 0; j < columns.length; j++) {
19696                                                                        TObjectName objectName = columns[j];
19697                                                                        if (objectName == null || "*".equals(getColumnName(objectName))) {
19698                                                                                continue;
19699                                                                        }
19700                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName,
19701                                                                                        false);
19702                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
19703                                                                }
19704                                                        } else {
19705                                                                if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) {
19706
19707                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
19708                                                                                TableColumn columnModel = tableModel.getColumns().get(j);
19709                                                                                if (exceptColumnList != null) {
19710                                                                                        boolean flag = false;
19711                                                                                        for (TObjectName objectName : exceptColumnList) {
19712                                                                                                if (getColumnName(objectName)
19713                                                                                                                .equals(getColumnName(columnModel.getColumnObject()))) {
19714                                                                                                        flag = true;
19715                                                                                                        break;
19716                                                                                                }
19717                                                                                        }
19718                                                                                        if (flag) {
19719                                                                                                continue;
19720                                                                                        }
19721                                                                                }
19722                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
19723                                                                        }
19724
19725                                                                        if (isStar && showStar) {
19726                                                                                TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
19727                                                                                                false);
19728                                                                                if (columnModel == null) {
19729                                                                                        if (tableModel.isCreateTable()) {
19730                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
19731                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
19732                                                                                                        relation.setShowStarRelation(true);
19733                                                                                                }
19734                                                                                        }
19735                                                                                } else {
19736                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
19737                                                                                        relation.setShowStarRelation(true);
19738                                                                                }
19739                                                                        }
19740                                                                } else {
19741                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
19742                                                                                        false);
19743                                                                        
19744                                                                        if(columnModel == null && containStarColumn(tableModel.getColumns())){
19745                                                                                columnModel = getStarColumn(tableModel.getColumns());
19746                                                                                if (columnModel != null && tableModel.getSubType() == SubType.record_type) {
19747                                                                                        if(!"*".equals(getColumnName(columnName))){
19748                                                                                                columnModel.bindStarLinkColumn(columnName);
19749                                                                                        }
19750                                                                                }
19751                                                                        }
19752                                                                        
19753                                                                        if (columnModel == null) {
19754                                                                                continue;
19755                                                                        }
19756                                                                        if (columnModel.hasStarLinkColumn()) {
19757                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel,
19758                                                                                                columnModel.getStarLinkColumnNames()
19759                                                                                                                .indexOf(DlineageUtil.getColumnName(columnName))));
19760                                                                        } else {
19761                                                                                if (isOut) {
19762                                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
19763                                                                                } else {
19764                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
19765                                                                                }
19766                                                                        }
19767                                                                        if (columnName.getSourceTable() != null
19768                                                                                        && columnName.getSourceTable().getTableType() == ETableSource.function) {
19769                                                                                analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(),
19770                                                                                                effectType);
19771                                                                        }
19772                                                                }
19773                                                        }
19774                                                        continue;
19775                                                }
19776                                        }
19777                                }
19778
19779                                if (table == null) {
19780                                        table = modelManager.getTable(stmt, columnName);
19781                                }
19782
19783                                if (table == null) {
19784                                        if (columnName.getTableToken() != null || !"*".equals(getColumnName(columnName))) {
19785                                                table = columnName.getSourceTable();
19786                                        }
19787                                        
19788                                        if (table == null && !SQLUtil.isEmpty(columnName.getTableString())) {
19789                                                table = modelManager.getTableFromColumn(columnName);
19790                                        }
19791                                }
19792
19793                                if (table == null) {
19794                                        if (tableList != null) {
19795                                                for (int j = 0; j < tableList.size(); j++) {
19796                                                        if (table != null)
19797                                                                break;
19798
19799                                                        TTable tTable = tableList.getTable(j);
19800                                                        if (tTable.getTableType().name().startsWith("open")) {
19801                                                                continue;
19802                                                        }
19803
19804                                                        if (tTable.getLinkedColumns() != null && tTable.getLinkedColumns().size() > 0) {
19805                                                                for (int z = 0; z < tTable.getLinkedColumns().size(); z++) {
19806                                                                        TObjectName refer = tTable.getLinkedColumns().getObjectName(z);
19807                                                                        if ("*".equals(getColumnName(refer)))
19808                                                                                continue;
19809                                                                        if (getColumnName(refer).equals(getColumnName(columnName))) {
19810                                                                                table = tTable;
19811                                                                                break;
19812                                                                        }
19813                                                                }
19814                                                        }
19815
19816                                                        if (table != null)
19817                                                                break;
19818
19819                                                        if (columnName.getTableToken() != null && (columnName.getTableToken().astext
19820                                                                        .equalsIgnoreCase(tTable.getName())
19821                                                                        || columnName.getTableToken().astext.equalsIgnoreCase(tTable.getAliasName()))) {
19822                                                                table = tTable;
19823                                                                break;
19824                                                        }
19825                                                }
19826                                        }
19827
19828                                        if (table == null) {
19829                                                for (int j = 0; j < tableList.size(); j++) {
19830                                                        if (table != null)
19831                                                                break;
19832
19833                                                        TTable tTable = tableList.getTable(j);
19834                                                        Object model = ModelBindingManager.get().getModel(tTable);
19835                                                        if (model instanceof Table) {
19836                                                                Table tableModel = (Table) model;
19837                                                                for (int z = 0; tableModel.getColumns() != null
19838                                                                                && z < tableModel.getColumns().size(); z++) {
19839                                                                        TableColumn refer = tableModel.getColumns().get(z);
19840                                                                        if (getColumnName(refer.getName()).equals(getColumnName(columnName))) {
19841                                                                                table = tTable;
19842                                                                                break;
19843                                                                        }
19844                                                                        if (refer.hasStarLinkColumn()) {
19845                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
19846                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
19847                                                                                                table = tTable;
19848                                                                                                break;
19849                                                                                        }
19850                                                                                }
19851                                                                        }
19852                                                                }
19853                                                        } else if (model instanceof QueryTable) {
19854                                                                QueryTable tableModel = (QueryTable) model;
19855                                                                for (int z = 0; tableModel.getColumns() != null
19856                                                                                && z < tableModel.getColumns().size(); z++) {
19857                                                                        ResultColumn refer = tableModel.getColumns().get(z);
19858                                                                        List<String> splits = SQLUtil.parseNames(columnName.toString());
19859                                                                        if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
19860                                                                                if (DlineageUtil.getIdentifierNormalColumnName(refer.getName())
19861                                                                                                .equals(DlineageUtil
19862                                                                                                                .getIdentifierNormalColumnName(getColumnName(splits.get(0))))) {
19863                                                                                        table = tTable;
19864                                                                                        break;
19865                                                                                }
19866                                                                        }
19867                                                                        else if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals(
19868                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
19869                                                                                table = tTable;
19870                                                                                break;
19871                                                                        }
19872                                                                        if (refer.hasStarLinkColumn()) {
19873                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
19874                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
19875                                                                                                table = tTable;
19876                                                                                                break;
19877                                                                                        }
19878                                                                                }
19879                                                                        }
19880                                                                }
19881                                                        }
19882                                                }
19883                                        }
19884                                }
19885
19886                                if (columnName.getTableToken() == null && "*".equals(getColumnName(columnName))) {
19887                                        if (!hasJoin(stmt)) {
19888                                                tables.add(table);
19889                                        } else {
19890                                                for (int j = 0; j < tableList.size(); j++) {
19891                                                        tables.add(tableList.getTable(j));
19892                                                }
19893                                        }
19894                                } else if (table != null) {
19895                                        tables.add(table);
19896                                }
19897
19898                                // 此处特殊处理,多表关联无法找到 column 所属的 Table, tTable.getLinkedColumns
19899                                // 也找不到,退而求其次采用第一个表
19900
19901                                if (stmt.getParentStmt() != null && isApplyJoin(stmt.getParentStmt())
19902                                                && (tableList != null && tableList.size() > 0)) {
19903                                        stmt = stmt.getParentStmt();
19904                                        TTable applyTable = tableList.getTable(0);
19905                                        if (modelManager.getModel(table) == null) {
19906                                                modelFactory.createTable(applyTable);
19907                                        }
19908                                }
19909
19910                                if (columnName.toString().indexOf(".")==-1 && isConstant(columnName)) {
19911                                        boolean isConstant = true;
19912                                        if (columnName.getSourceTable() != null) {
19913                                                Table tableModel = modelManager.getTableByName(
19914                                                                DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString()));
19915                                                if (tableModel != null && tableModel.getColumns() != null) {
19916                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
19917                                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
19918                                                                                getColumnName(tableModel.getColumns().get(j).getName()))) {
19919                                                                        isConstant = false;
19920                                                                        break;
19921                                                                }
19922                                                        }
19923                                                }
19924                                        }
19925
19926                                        if (isConstant) {
19927                                                if (option.isShowConstantTable()) {
19928                                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
19929                                                        TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false);
19930                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
19931                                                }
19932                                                continue;
19933                                        }
19934                                }
19935
19936                                if (tableList != null && tableList.size() != 0 && tables.size() == 0
19937                                                && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) {
19938                                        if (modelManager.getModel(stmt) instanceof ResultSet) {
19939                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt);
19940                                                boolean find = false;
19941                                                for (ResultColumn resultColumn : resultSetModel.getColumns()) {
19942                                                        if(resultColumn.equals(modelObject)) {
19943                                                                continue;
19944                                                        }
19945                                                        if (!TSQLEnv.isAliasReferenceForbidden[option.getVendor().ordinal()]) {
19946                                                                if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) {
19947                                                                        if (resultColumn.getColumnObject() != null) {
19948                                                                                int startToken = resultColumn.getColumnObject().getStartToken().posinlist;
19949                                                                                int endToken = resultColumn.getColumnObject().getEndToken().posinlist;
19950                                                                                if (columnName.getStartToken().posinlist >= startToken
19951                                                                                                && columnName.getEndToken().posinlist <= endToken) {
19952                                                                                        continue;
19953                                                                                }
19954                                                                        }
19955                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
19956                                                                        find = true;
19957                                                                        break;
19958                                                                }
19959                                                        }
19960                                                }
19961                                                if (find) {
19962                                                        continue;
19963                                                }
19964                                        }
19965                                        
19966                                        TObjectName pseudoTableName = new TObjectName();
19967                                        pseudoTableName.setString("pseudo_table_include_orphan_column");
19968                                        Table pseudoTable = modelFactory.createTableByName(pseudoTableName);
19969                                        pseudoTable.setPseudo(true);
19970                                        modelFactory.createTableColumn(pseudoTable, columnName, true);
19971
19972                                        if (isLinkOrphanColumnToFirstTable()) {
19973                                                TTable orphanTable = tableList.getTable(0);
19974                                                tables.add(orphanTable);
19975                                                Object tableModel = modelManager.getModel(orphanTable);
19976                                                if (tableModel == null) {
19977                                                        if(orphanTable.getSubquery()!=null) {
19978                                                                QueryTable queryTable = modelFactory.createQueryTable(orphanTable);
19979                                                                TSelectSqlStatement subquery = orphanTable.getSubquery();
19980                                                                analyzeSelectStmt(subquery);
19981                                                        }
19982                                                        else {
19983                                                                tableModel = modelFactory.createTable(orphanTable);
19984                                                        }
19985                                                }
19986                                                if (tableModel instanceof Table) {
19987                                                        TableColumn orphanColum = modelFactory.createTableColumn((Table) tableModel, columnName, false);
19988                                                        if(orphanColum!=null) {
19989                                                                ErrorInfo errorInfo = new ErrorInfo();
19990                                                                errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN);
19991                                                                errorInfo.setErrorMessage("Link orphan column [" + columnName.toString()
19992                                                                                + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]");
19993                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo,
19994                                                                                columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
19995                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo,
19996                                                                                columnName.getEndToken().columnNo + columnName.getEndToken().astext.length(),
19997                                                                                ModelBindingManager.getGlobalHash()));
19998                                                                errorInfo.fillInfo(this);
19999                                                                errorInfos.add(errorInfo);
20000                                                        }
20001                                                        if (orphanTable.getSubquery() != null) {
20002                                                                TSelectSqlStatement subquery = orphanTable.getSubquery();
20003                                                                if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) {
20004                                                                        TTable subqueryTable = subquery.getTables().getTable(0);
20005                                                                        Object sourceTable = modelManager.getModel(subqueryTable);
20006                                                                        if(sourceTable instanceof Table) {
20007                                                                                modelFactory.createTableColumn((Table) sourceTable, columnName, false);
20008                                                                        }
20009                                                                        else if(sourceTable instanceof ResultSet) {
20010                                                                                modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false);
20011                                                                        }
20012                                                                }
20013                                                        }
20014                                                        else if (orphanTable.getCTE()!=null && orphanTable.getCTE().getSubquery() != null) {
20015                                                                TSelectSqlStatement subquery = orphanTable.getCTE().getSubquery();
20016                                                                if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) {
20017                                                                        TTable subqueryTable = subquery.getTables().getTable(0);
20018                                                                        Object sourceTable = modelManager.getModel(subqueryTable);
20019                                                                        if(sourceTable instanceof Table) {
20020                                                                                modelFactory.createTableColumn((Table) sourceTable, columnName, false);
20021                                                                        }
20022                                                                        else if(sourceTable instanceof ResultSet) {
20023                                                                                modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false);
20024                                                                        }
20025                                                                }
20026                                                        }
20027                                                }
20028                                                
20029                                                linkedFirstTable = true;
20030                                        }
20031                                }
20032                        }
20033
20034                        for (int k = 0; k < tables.size(); k++) {
20035                                TTable table = tables.get(k);
20036                                if (table != null) {
20037                                        Object object = modelManager.getModel(table);
20038                                        if(object instanceof PivotedTable) {
20039                                                TPivotClause clause = (TPivotClause)((PivotedTable)object).getGspObject();
20040                                                if(clause.getAliasClause()!=null) {
20041                                                        object = modelManager.getModel(clause.getAliasClause());
20042                                                }
20043                                        }
20044                                        if (object == null && table.getTableType() == ETableSource.objectname) {
20045                                                if (table.getCTE() != null) {
20046                                                        QueryTable queryTable = modelFactory.createQueryTable(table);
20047                                                        TSelectSqlStatement subquery = table.getCTE().getSubquery();
20048                                                        analyzeSelectStmt(subquery);
20049                                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
20050
20051                                                        if (resultSetModel != null && resultSetModel != queryTable
20052                                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
20053                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
20054                                                                impactRelation.setEffectType(EffectType.select);
20055                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
20056                                                                                resultSetModel.getRelationRows()));
20057                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
20058                                                                                queryTable.getRelationRows()));
20059                                                        }
20060
20061                                                        if (resultSetModel != null && resultSetModel != queryTable) {
20062                                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
20063                                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
20064                                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
20065                                                                                        sourceColumn);
20066
20067                                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
20068                                                                        queryRalation.setEffectType(EffectType.select);
20069                                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
20070                                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
20071                                                                }
20072                                                        }
20073                                                        
20074                                                        object = queryTable;
20075                                                        
20076                                                } else {
20077                                                        object = modelFactory.createTable(table);
20078                                                }
20079                                        }
20080                                        if (object instanceof Function) {
20081                                                relation.addSource(new ResultColumnRelationshipElement(((Function)object).getColumns().get(0)));
20082                                                continue;
20083                                        } else if (object instanceof ResultSet && !(object instanceof QueryTable)) {
20084                                                //Object tableModel = modelManager.getModel(columnName.getSourceTable());
20085                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
20086                                                                (ResultSet)object);
20087                                                if(table.getTableType() == ETableSource.function && !relation.getSources().isEmpty()) {
20088                                                        relation.getSources().stream().reduce((first, second) -> second).get().addTransform(Transform.FUNCTION, table);
20089                                                }
20090                                                continue;
20091                                        }
20092                                        else if (object instanceof Table) {
20093                                                Table tableModel = (Table) modelManager.getModel(table);
20094                                                if (tableModel != null) {
20095                                                        if (!isStar && "*".equals(getColumnName(columnName))) {
20096                                                                TObjectName[] columns = modelManager.getTableColumns(table);
20097                                                                for (int j = 0; j < columns.length; j++) {
20098                                                                        TObjectName objectName = columns[j];
20099                                                                        if (objectName == null || ("*".equals(getColumnName(objectName)) && tableModel.isDetermined())) {
20100                                                                                continue;
20101                                                                        }
20102                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName,
20103                                                                                        false);
20104                                                                        if(columnModel == null) {
20105                                                                                continue;
20106                                                                        }
20107                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20108                                                                }
20109                                                        } else {
20110                                                                if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) {
20111                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
20112                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
20113                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
20114                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
20115                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
20116                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
20117                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
20118                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
20119                                                                                        }
20120                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20121                                                                                        if(tableModel.isDetermined()) {
20122                                                                                                resultSet.getColumns().clear();
20123                                                                                        }
20124                                                                                }
20125                                                                        }
20126                                                                        
20127                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
20128                                                                                TableColumn columnModel = tableModel.getColumns().get(j);
20129                                                                                if (exceptColumnList != null) {
20130                                                                                        boolean flag = false;
20131                                                                                        for (TObjectName objectName : exceptColumnList) {
20132                                                                                                if (getColumnName(objectName)
20133                                                                                                                .equals(getColumnName(columnModel.getColumnObject()))) {
20134                                                                                                        flag = true;
20135                                                                                                        break;
20136                                                                                                }
20137                                                                                        }
20138                                                                                        if (flag) {
20139                                                                                                continue;
20140                                                                                        }
20141                                                                                }
20142                                                                                
20143                                                                                if (replaceAsIdentifierMap.containsKey(tableModel.getColumns().get(j).getName())) {
20144                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableModel.getColumns().get(j).getName());
20145                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20146                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(tableModel.getColumns().get(j).getName()));
20147                                                                                        Transform transform = new Transform();
20148                                                                                        transform.setType(Transform.EXPRESSION);
20149                                                                                        TObjectName expression = new TObjectName();
20150                                                                                        expression.setString(expr.first);
20151                                                                                transform.setCode(expression);
20152                                                                                        resultColumn.setTransform(transform);
20153                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
20154                                                                                } else {
20155                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
20156                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
20157                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
20158                                                                                                                columnModel.getColumnObject());
20159                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
20160                                                                                                relation1.setEffectType(effectType);
20161                                                                                                relation1.setProcess(process);
20162                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
20163                                                                                                relation1.addSource(new TableColumnRelationshipElement(columnModel));
20164                                                                                        }
20165                                                                                        else {
20166                                                                                                relation.addSource(
20167                                                                                                        new TableColumnRelationshipElement(columnModel));
20168                                                                                        }
20169                                                                                }
20170                                                                        }
20171
20172                                                                        if (isStar && showStar) {
20173                                                                                TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
20174                                                                                                false);
20175                                                                                if (columnModel == null) {
20176                                                                                        if(tableModel.isCreateTable()) {
20177                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
20178                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20179                                                                                                        relation.setShowStarRelation(true);
20180                                                                                                }
20181                                                                                        }
20182                                                                                } else {
20183                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20184                                                                                        relation.setShowStarRelation(true);
20185                                                                                }
20186                                                                        }
20187                                                                } else {
20188                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
20189                                                                                        false);
20190                                                                        if(columnModel == null) {
20191                                                                                if(tableModel.isCreateTable()) {
20192                                                                                        boolean flag = false;
20193                                                                                        if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvbigquery || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvredshift) {
20194                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
20195                                                                                                        if(tableColumn.isStruct()) {
20196                                                                                                                List<String> names = SQLUtil.parseNames(tableColumn.getName());
20197                                                                                                                if (modelObject instanceof TableColumn) {
20198                                                                                                                        TableColumn targetColumn = (TableColumn) modelObject;
20199                                                                                                                        if (targetColumn.isStruct()) {
20200                                                                                                                                List<String> targetNames = SQLUtil
20201                                                                                                                                                .parseNames(targetColumn.getName());
20202                                                                                                                                if (!getColumnName(targetNames.get(0))
20203                                                                                                                                                .equals(getColumnName(names.get(0)))) {
20204                                                                                                                                        continue;
20205                                                                                                                                }
20206                                                                                                                        }
20207                                                                                                                }
20208                                                                                                                else if (modelObject instanceof ResultColumn) {
20209                                                                                                                        ResultColumn targetColumn = (ResultColumn) modelObject;
20210                                                                                                                        if (targetColumn.isStruct()) {
20211                                                                                                                                List<String> targetNames = SQLUtil
20212                                                                                                                                                .parseNames(targetColumn.getName());
20213                                                                                                                                if (!getColumnName(targetNames.get(0))
20214                                                                                                                                                .equals(getColumnName(names.get(0)))) {
20215                                                                                                                                        continue;
20216                                                                                                                                }
20217                                                                                                                        }
20218                                                                                                                }
20219                                                                                                                for(String name: names) {
20220                                                                                                                        if (getColumnName(name)
20221                                                                                                                                        .equals(getColumnName(modelObject.toString()))) {
20222                                                                                                                                relation.addSource(
20223                                                                                                                                                new TableColumnRelationshipElement(tableColumn));
20224                                                                                                                                flag = true;
20225                                                                                                                                if (modelObject instanceof ResultColumn) {
20226                                                                                                                                        ((ResultColumn)modelObject).setStruct(true);
20227                                                                                                                                }
20228                                                                                                                                else if (modelObject instanceof TableColumn) {
20229                                                                                                                                        ((TableColumn)modelObject).setStruct(true);
20230                                                                                                                                }
20231                                                                                                                                break;
20232                                                                                                                        }
20233                                                                                                                }
20234                                                                                                        }
20235                                                                                                        else if (getColumnName(tableColumn.getName())
20236                                                                                                                        .equals(getColumnName(modelObject.toString()))) {
20237                                                                                                                relation.addSource(
20238                                                                                                                                new TableColumnRelationshipElement(tableColumn));
20239                                                                                                                flag = true;
20240                                                                                                                break;
20241                                                                                                        }
20242                                                                                                }
20243                                                                                                if (modelObject instanceof TableColumn) {
20244                                                                                                        TableColumn column = (TableColumn) modelObject;
20245                                                                                                        for (TableColumn tableColumn : tableModel.getColumns()) {
20246                                                                                                                if (tableColumn.getColumnIndex() == null) {
20247                                                                                                                        continue;
20248                                                                                                                }
20249                                                                                                                if (tableColumn.getName().toLowerCase()
20250                                                                                                                                .indexOf(column.getName().toLowerCase()) == -1
20251                                                                                                                                && tableColumn.getName().toLowerCase()
20252                                                                                                                                                .indexOf(column.getColumnObject().toString()
20253                                                                                                                                                                .toLowerCase()) == -1) {
20254                                                                                                                        continue;
20255                                                                                                                }
20256                                                                                                                flag = true;
20257                                                                                                                relation.addSource(
20258                                                                                                                                new TableColumnRelationshipElement(tableColumn));
20259                                                                                                                relation.setShowStarRelation(true);
20260                                                                                                        }
20261                                                                                                        if (flag)
20262                                                                                                                break;
20263
20264                                                                                                } else if (modelObject instanceof ResultColumn) {
20265                                                                                                        ResultColumn column = (ResultColumn) modelObject;
20266                                                                                                        for (TableColumn tableColumn : tableModel.getColumns()) {
20267                                                                                                                if (tableColumn.getColumnIndex() == null) {
20268                                                                                                                        continue;
20269                                                                                                                }
20270                                                                                                                if (tableColumn.getName().toLowerCase()
20271                                                                                                                                .indexOf(column.getName().toLowerCase()) == -1
20272                                                                                                                                && tableColumn.getName().toLowerCase()
20273                                                                                                                                                .indexOf(column.getColumnObject().toString()
20274                                                                                                                                                                .toLowerCase()) == -1) {
20275                                                                                                                        continue;
20276                                                                                                                }
20277                                                                                                                flag = true;
20278                                                                                                                relation.addSource(
20279                                                                                                                                new TableColumnRelationshipElement(tableColumn));
20280                                                                                                                relation.setShowStarRelation(true);
20281                                                                                                        }
20282                                                                                                        if (flag)
20283                                                                                                                break;
20284
20285                                                                                                }
20286                                                                                        }
20287                                                                                        if (!flag 
20288                                                                                                        && (isStar 
20289                                                                                                                        || getColumnName(columnName).equals(getColumnName(tableModel.getName()))
20290                                                                                                                        || getColumnName(columnName).equals(getColumnName(tableModel.getAlias())))) {
20291                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
20292                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20293                                                                                                        relation.setShowStarRelation(true);
20294                                                                                                }
20295                                                                                        }
20296                                                                                }
20297                                                                        }
20298                                                                        else {
20299                                                                                if (linkedFirstTable) {
20300                                                                                        if (columnName.getCandidateTables() != null
20301                                                                                                        && columnName.getCandidateTables().size() > 1) {
20302                                                                                                List<Object> candidateParents = new ArrayList<Object>();
20303                                                                                                for(TTable tableItem: columnName.getCandidateTables()) {
20304                                                                                                        Object model = modelManager.getModel(tableItem);
20305                                                                                                        if(model!=null) {
20306                                                                                                                candidateParents.add(model);
20307                                                                                                        }
20308                                                                                                }
20309                                                                                                if (candidateParents.size() > 1) {
20310                                                                                                        columnModel.setCandidateParents(candidateParents);
20311                                                                                                }
20312                                                                                        }
20313                                                                                }
20314                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
20315                                                                                relation.setShowStarRelation(true);
20316                                                                                if (columnName.getSourceTable() != null
20317                                                                                                && columnName.getSourceTable().getTableType() == ETableSource.function) {
20318                                                                                        analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(),
20319                                                                                                        effectType);
20320                                                                                }
20321                                                                        }
20322                                                                }
20323                                                        }
20324                                                }
20325                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
20326                                                QueryTable queryTable = (QueryTable) modelManager.getModel(table);
20327
20328                                                TObjectNameList cteColumns = null;
20329                                                TSelectSqlStatement subquery = null;
20330                                                if (queryTable.getTableObject().getCTE() != null) {
20331                                                        subquery = queryTable.getTableObject().getCTE().getSubquery();
20332                                                        cteColumns = queryTable.getTableObject().getCTE().getColumnList();
20333                                                } else if (queryTable.getTableObject().getAliasClause() != null
20334                                                                && queryTable.getTableObject().getAliasClause().getColumns() != null) {
20335
20336                                                } else if (queryTable.getTableObject().getTableExpr() != null
20337                                                                && queryTable.getTableObject().getTableExpr().getSubQuery() != null) {
20338                                                        subquery = queryTable.getTableObject().getTableExpr().getSubQuery();
20339                                                } else {
20340                                                        subquery = queryTable.getTableObject().getSubquery();
20341                                                }
20342
20343                                                if (cteColumns != null) {
20344                                                        for (int j = 0; j < cteColumns.size(); j++) {
20345                                                                modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
20346                                                        }
20347                                                }
20348
20349                                                if (subquery != null && subquery.isCombinedQuery()) {
20350                                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
20351                                                                        .getModel(subquery);
20352
20353                                                        if (selectSetResultSetModel != null
20354                                                                        && !selectSetResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
20355                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
20356                                                                impactRelation.setEffectType(EffectType.select);
20357                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
20358                                                                                selectSetResultSetModel.getRelationRows()));
20359                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
20360                                                                                queryTable.getRelationRows()));
20361                                                        }
20362
20363                                                        if (selectSetResultSetModel != null) {
20364                                                                if (getColumnName(columnName).equals("*")) {
20365                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
20366                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
20367                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
20368                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
20369                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
20370                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
20371                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
20372                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
20373                                                                                        }
20374                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20375                                                                                        if(selectSetResultSetModel.isDetermined()) {
20376                                                                                                resultSet.getColumns().clear();
20377                                                                                        }
20378                                                                                }
20379                                                                        }
20380                                                                        
20381                                                                        
20382                                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
20383                                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
20384                                                                                if (cteColumns != null) {
20385                                                                                        if (j < cteColumns.size()) {
20386                                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
20387
20388                                                                                                if (exceptColumnList != null) {
20389                                                                                                        boolean flag = false;
20390                                                                                                        for (TObjectName objectName : exceptColumnList) {
20391                                                                                                                if (getColumnName(objectName)
20392                                                                                                                                .equals(getColumnName(targetColumn.getName()))) {
20393                                                                                                                        flag = true;
20394                                                                                                                        break;
20395                                                                                                                }
20396                                                                                                        }
20397                                                                                                        if (flag) {
20398                                                                                                                continue;
20399                                                                                                        }
20400                                                                                                }
20401
20402                                                                                                if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
20403                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
20404                                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20405                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
20406                                                                                                        Transform transform = new Transform();
20407                                                                                                        transform.setType(Transform.EXPRESSION);
20408                                                                                                        TObjectName expression = new TObjectName();
20409                                                                                                        expression.setString(expr.first);
20410                                                                                                transform.setCode(expression);
20411                                                                                                        resultColumn.setTransform(transform);
20412                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
20413                                                                                                } else {
20414                                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
20415                                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
20416                                                                                                                TObjectName resultColumnName = new TObjectName();
20417                                                                                                                resultColumnName.setString(targetColumn.getName());
20418                                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
20419                                                                                                                                resultColumnName);
20420                                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
20421                                                                                                                relation1.setEffectType(effectType);
20422                                                                                                                relation1.setProcess(process);
20423                                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
20424                                                                                                                relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
20425                                                                                                        }
20426                                                                                                        else {
20427                                                                                                                relation.addSource(
20428                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
20429                                                                                                        }
20430                                                                                                }
20431                                                                                                
20432                                                                                        }
20433                                                                                } else {
20434                                                                                        ResultColumn targetColumn = modelFactory
20435                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
20436
20437                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
20438                                                                                                        .createDataFlowRelation();
20439                                                                                        combinedQueryRelation.setEffectType(effectType);
20440                                                                                        combinedQueryRelation
20441                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
20442                                                                                        combinedQueryRelation
20443                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
20444
20445                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
20446                                                                                }
20447                                                                        }
20448                                                                        break;
20449                                                                } else {
20450                                                                        boolean flag = false;
20451
20452                                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
20453                                                                                ResultColumn sourceColumn = selectSetResultSetModel
20454                                                                                                .getColumns().get(j);
20455                                                                                List<String> splits = SQLUtil.parseNames(columnName.toString());        
20456                                                                                if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
20457                                                                                        if (getColumnName(sourceColumn.getName())
20458                                                                                                        .equalsIgnoreCase(getColumnName(splits.get(0)))) {
20459                                                                                                ResultColumn targetColumn = modelFactory
20460                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
20461
20462                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
20463                                                                                                                .createDataFlowRelation();
20464                                                                                                combinedQueryRelation.setEffectType(effectType);
20465                                                                                                combinedQueryRelation.setTarget(
20466                                                                                                                new ResultColumnRelationshipElement(targetColumn));
20467                                                                                                combinedQueryRelation.addSource(
20468                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
20469
20470                                                                                                relation.addSource(
20471                                                                                                                new ResultColumnRelationshipElement(targetColumn));
20472                                                                                                flag = true;
20473                                                                                                break;
20474                                                                                        }
20475                                                                                }
20476                                                                                else if (getColumnName(sourceColumn.getName())
20477                                                                                                .equalsIgnoreCase(getColumnName(columnName))) {
20478                                                                                        ResultColumn targetColumn = modelFactory
20479                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
20480
20481                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
20482                                                                                                        .createDataFlowRelation();
20483                                                                                        combinedQueryRelation.setEffectType(effectType);
20484                                                                                        combinedQueryRelation
20485                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
20486                                                                                        combinedQueryRelation
20487                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
20488
20489                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
20490                                                                                        flag = true;
20491                                                                                        break;
20492                                                                                }
20493                                                                                else if (sourceColumn instanceof SelectSetResultColumn && ((SelectSetResultColumn)sourceColumn).getAliasSet().size() > 1) {
20494                                                                                        for (String alias : ((SelectSetResultColumn)sourceColumn).getAliasSet()) {
20495                                                                                                if (getColumnName(alias).equalsIgnoreCase(getColumnName(columnName))) {
20496                                                                                                        ResultColumn targetColumn = modelFactory
20497                                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
20498
20499                                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
20500                                                                                                                        .createDataFlowRelation();
20501                                                                                                        combinedQueryRelation.setEffectType(effectType);
20502                                                                                                        combinedQueryRelation.setTarget(
20503                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
20504                                                                                                        combinedQueryRelation.addSource(
20505                                                                                                                        new ResultColumnRelationshipElement(sourceColumn));
20506
20507                                                                                                        relation.addSource(
20508                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
20509                                                                                                        flag = true;
20510                                                                                                        break;
20511                                                                                                }
20512                                                                                        }
20513                                                                                        if (flag) {
20514                                                                                                break;
20515                                                                                        }
20516                                                                                }
20517                                                                        }
20518
20519                                                                        if (flag) {
20520                                                                                break;
20521                                                                        } else if (columnIndex != -1) {
20522                                                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
20523                                                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
20524                                                                                        if (!sourceColumn.getStarLinkColumns().isEmpty()) {
20525                                                                                                if (cteColumns != null) {
20526                                                                                                        if (j < cteColumns.size()) {
20527                                                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
20528                                                                                                                relation.addSource(
20529                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
20530                                                                                                        }
20531                                                                                                } 
20532                                                                                                else {
20533                                                                                                        if(sourceColumn.hasStarLinkColumn()) {
20534                                                                                                                for (TObjectName linkColumn : sourceColumn.getStarLinkColumnList()) {
20535                                                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
20536                                                                                                                                ResultColumn targetColumn = modelFactory
20537                                                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
20538
20539                                                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
20540                                                                                                                                                .createDataFlowRelation();
20541                                                                                                                                combinedQueryRelation.setEffectType(effectType);
20542                                                                                                                                combinedQueryRelation.setTarget(
20543                                                                                                                                                new ResultColumnRelationshipElement(targetColumn, linkColumn));
20544                                                                                                                                combinedQueryRelation.addSource(
20545                                                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
20546
20547                                                                                                                                relation.addSource(
20548                                                                                                                                                new ResultColumnRelationshipElement(targetColumn, linkColumn));
20549                                                                                                                                flag = true;
20550                                                                                                                                break;
20551                                                                                                                        }
20552                                                                                                                }
20553                                                                                                        }
20554                                                                                                        
20555                                                                                                        if(!flag) {
20556                                                                                                                ResultColumn targetColumn = modelFactory
20557                                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
20558
20559                                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
20560                                                                                                                                .createDataFlowRelation();
20561                                                                                                                combinedQueryRelation.setEffectType(effectType);
20562                                                                                                                combinedQueryRelation.setTarget(
20563                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
20564                                                                                                                combinedQueryRelation.addSource(
20565                                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
20566
20567                                                                                                                relation.addSource(
20568                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
20569                                                                                                        }
20570                                                                                                }
20571                                                                                                flag = true;
20572                                                                                                break;
20573                                                                                        }
20574                                                                                }
20575                                                                        }
20576
20577                                                                        if (flag) {
20578                                                                                break;
20579                                                                        } else if (columnIndex < selectSetResultSetModel.getColumns().size()
20580                                                                                        && columnIndex != -1) {
20581                                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns()
20582                                                                                                .get(columnIndex);
20583                                                                                if (cteColumns != null) {
20584                                                                                        if (columnIndex < cteColumns.size()) {
20585                                                                                                ResultColumn targetColumn = queryTable.getColumns().get(columnIndex);
20586                                                                                                relation.addSource(new ResultColumnRelationshipElement(targetColumn));
20587                                                                                        }
20588                                                                                } else {
20589                                                                                        ResultColumn targetColumn = modelFactory
20590                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
20591
20592                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
20593                                                                                                        .createDataFlowRelation();
20594                                                                                        combinedQueryRelation.setEffectType(effectType);
20595                                                                                        combinedQueryRelation
20596                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
20597                                                                                        combinedQueryRelation
20598                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
20599
20600                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
20601                                                                                }
20602                                                                                flag = true;
20603                                                                                break;
20604                                                                        }
20605
20606                                                                        if (flag) {
20607                                                                                break;
20608                                                                        }
20609                                                                }
20610                                                        } else if (cteColumns != null) {
20611                                                                if (getColumnName(columnName).equals("*")) {
20612                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
20613                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
20614                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
20615                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
20616                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
20617                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
20618                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
20619                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
20620                                                                                        }
20621                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20622                                                                                        
20623                                                                                        if (columnName.getSourceColumn() != null) {
20624                                                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
20625                                                                                                if (model instanceof ResultColumn && ((ResultColumn)model).getResultSet().isDetermined()) {
20626                                                                                                        resultSet.getColumns().clear();
20627                                                                                                }
20628                                                                                        } else if (columnName.getSourceTable() != null) {
20629                                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
20630                                                                                                if (tableModel instanceof Table && ((Table)tableModel).isDetermined()) {
20631                                                                                                        resultSet.getColumns().clear();
20632                                                                                                }
20633                                                                                        }
20634                                                                                }
20635                                                                        }
20636                                                                        
20637                                                                        for (int j = 0; j < cteColumns.size(); j++) {
20638                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
20639
20640                                                                                if (exceptColumnList != null) {
20641                                                                                        boolean flag = false;
20642                                                                                        for (TObjectName objectName : exceptColumnList) {
20643                                                                                                if (getColumnName(objectName)
20644                                                                                                                .equals(getColumnName(targetColumn.getName()))) {
20645                                                                                                        flag = true;
20646                                                                                                        break;
20647                                                                                                }
20648                                                                                        }
20649                                                                                        if (flag) {
20650                                                                                                continue;
20651                                                                                        }
20652                                                                                }
20653
20654                                                                                if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
20655                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
20656                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20657                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
20658                                                                                        Transform transform = new Transform();
20659                                                                                        transform.setType(Transform.EXPRESSION);
20660                                                                                        TObjectName expression = new TObjectName();
20661                                                                                        expression.setString(expr.first);
20662                                                                                transform.setCode(expression);
20663                                                                                        resultColumn.setTransform(transform);
20664                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
20665                                                                                } else {
20666                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
20667                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
20668                                                                                                TObjectName resultColumnName = new TObjectName();
20669                                                                                                resultColumnName.setString(targetColumn.getName());
20670                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
20671                                                                                                                resultColumnName);
20672                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
20673                                                                                                relation1.setEffectType(effectType);
20674                                                                                                relation1.setProcess(process);
20675                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
20676                                                                                                relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
20677                                                                                        }
20678                                                                                        else {
20679                                                                                                relation.addSource(
20680                                                                                                        new ResultColumnRelationshipElement(targetColumn));
20681                                                                                        }
20682                                                                                }
20683                                                                        }
20684                                                                        break;
20685                                                                } else {
20686                                                                        boolean flag = false;
20687
20688                                                                        for (int j = 0; j < cteColumns.size(); j++) {
20689                                                                                TObjectName sourceColumn = cteColumns.getObjectName(j);
20690
20691                                                                                if (getColumnName(sourceColumn).equalsIgnoreCase(getColumnName(columnName))) {
20692                                                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
20693
20694                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
20695                                                                                        flag = true;
20696                                                                                        break;
20697                                                                                }
20698                                                                        }
20699
20700                                                                        if (flag) {
20701                                                                                break;
20702                                                                        }
20703                                                                }
20704                                                        }
20705
20706                                                        if (columnName.getSourceColumn() != null) {
20707                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
20708                                                                if (model instanceof ResultColumn) {
20709                                                                        ResultColumn resultColumn = (ResultColumn) model;
20710                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
20711                                                                }
20712                                                        } else if (columnName.getSourceTable() != null) {
20713                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
20714                                                                if (tableModel instanceof Table) {
20715                                                                        Object model = modelManager
20716                                                                                        .getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName));
20717                                                                        if (model instanceof TableColumn) {
20718                                                                                relation.addSource(new TableColumnRelationshipElement((TableColumn) model));
20719                                                                        }
20720                                                                }
20721                                                        }
20722                                                } else {
20723                                                        List<ResultColumn> columns = queryTable.getColumns();
20724                                                        if (getColumnName(columnName).equals("*")) {
20725                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
20726                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
20727                                                                if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
20728                                                                        TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
20729                                                                        if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
20730                                                                                for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
20731                                                                                        replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
20732                                                                                        replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
20733                                                                                }
20734                                                                                ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20735                                                                                if(queryTable.isDetermined()) {
20736                                                                                        resultSet.getColumns().clear();
20737                                                                                }
20738                                                                        }
20739                                                                }
20740                                                                
20741                                                                int index = 0;
20742                                                                for (int j = 0; j < queryTable.getColumns().size(); j++) {
20743                                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
20744                                                                        if (exceptColumnList != null) {
20745                                                                                boolean flag = false;
20746                                                                                for (TObjectName objectName : exceptColumnList) {
20747                                                                                        if (getColumnName(objectName)
20748                                                                                                        .equals(getColumnName(targetColumn.getName()))) {
20749                                                                                                flag = true;
20750                                                                                                break;
20751                                                                                        }
20752                                                                                }
20753                                                                                if (flag) {
20754                                                                                        continue;
20755                                                                                }
20756                                                                        }
20757                                                                        
20758                                                                        if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
20759                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
20760                                                                                ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
20761                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
20762                                                                                Transform transform = new Transform();
20763                                                                                transform.setType(Transform.EXPRESSION);
20764                                                                                TObjectName expression = new TObjectName();
20765                                                                                expression.setString(expr.first);
20766                                                                        transform.setCode(expression);
20767                                                                                resultColumn.setTransform(transform);
20768                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
20769                                                                        } else {
20770                                                                                if(!replaceAsIdentifierMap.isEmpty()) {
20771                                                                                        ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
20772                                                                                        TObjectName resultColumnName = new TObjectName();
20773                                                                                        resultColumnName.setString(targetColumn.getName());
20774                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
20775                                                                                                        resultColumnName);
20776                                                                                        DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
20777                                                                                        relation1.setEffectType(effectType);
20778                                                                                        relation1.setProcess(process);
20779                                                                                        relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
20780                                                                                        relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
20781                                                                                }
20782                                                                                else {
20783                                                                                        relation.addSource(
20784                                                                                                new ResultColumnRelationshipElement(targetColumn));
20785                                                                                }
20786                                                                        }
20787                                                                        index++;
20788                                                                }
20789                                                        } else {
20790                                                                if (table.getCTE() != null) {
20791                                                                        
20792                                                                        if (modelObject instanceof TableColumn) {
20793                                                                                Table modelTable = ((TableColumn) modelObject).getTable();
20794                                                                                if (modelTable.getSubType() == SubType.unnest) {
20795                                                                                        boolean find = false;
20796                                                                                        for (k = 0; k < columns.size(); k++) {
20797                                                                                                ResultColumn column = columns.get(k);
20798                                                                                                if (column.isStruct()) {
20799                                                                                                        List<String> names = SQLUtil.parseNames(column.getName());
20800                                                                                                        for (String name : names) {
20801                                                                                                                if (getColumnName(name).equals(getColumnName(columnName))) {
20802                                                                                                                        DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation();
20803                                                                                                                        unnestRelation.setEffectType(effectType);
20804                                                                                                                        unnestRelation.setProcess(process);
20805                                                                                                                        unnestRelation.addSource(new ResultColumnRelationshipElement(
20806                                                                                                                                        column, columnName));
20807                                                                                                                        TObjectName unnestTableColumnName = new TObjectName();
20808                                                                                                                        unnestTableColumnName.setString(names.get(names.size()-1));
20809                                                                                                                        TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true);
20810                                                                                                                        unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
20811                                                                                                                        find = true;
20812                                                                                                                }
20813                                                                                                        }
20814                                                                                                        List<String> names1 = SQLUtil.parseNames(column.getName());
20815                                                                                                        if (names.size() == 1 && names1.size() >= 1) {
20816                                                                                                                for (String name : names1) {
20817                                                                                                                        if (getColumnName(name)
20818                                                                                                                                        .equals(getColumnName(column.getName()))) {
20819                                                                                                                                DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation();
20820                                                                                                                                unnestRelation.setEffectType(effectType);
20821                                                                                                                                unnestRelation.setProcess(process);
20822                                                                                                                                unnestRelation.addSource(new ResultColumnRelationshipElement(
20823                                                                                                                                                column, columnName));
20824                                                                                                                                TObjectName unnestTableColumnName = new TObjectName();
20825                                                                                                                                unnestTableColumnName.setString(names1.get(names.size()-1));
20826                                                                                                                                TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true);
20827                                                                                                                                unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
20828                                                                                                                                find = true;
20829                                                                                                                        }
20830                                                                                                                }
20831                                                                                                        }
20832                                                                                                }
20833                                                                                        }
20834                                                                                        if (find) {
20835                                                                                                modelTable.getColumns().remove(modelObject);
20836                                                                                                break;
20837                                                                                        }
20838                                                                                }
20839                                                                        }
20840                                                                        
20841                                                                        for (k = 0; k < columns.size(); k++) {
20842                                                                                ResultColumn column = columns.get(k);
20843                                                                                if ("*".equals(column.getName())) {
20844                                                                                        if (!containsStarColumn(column, columnName)) {
20845                                                                                                column.bindStarLinkColumn(columnName);
20846                                                                                        }
20847                                                                                        relation.addSource(new ResultColumnRelationshipElement(column, columnName));
20848                                                                                } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
20849                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
20850                                                                                        if (!column.equals(modelObject)) {
20851                                                                                                relation.addSource(
20852                                                                                                                new ResultColumnRelationshipElement(column, columnName));
20853                                                                                        }
20854                                                                                        break;
20855                                                                                } else if(column.isStruct()) {
20856                                                                                        List<String> names = SQLUtil.parseNames(column.getName());
20857                                                                                        for(String name: names) {
20858                                                                                                if (getColumnName(name)
20859                                                                                                                .equals(getColumnName(columnName))) {
20860                                                                                                        relation.addSource(
20861                                                                                                                        new ResultColumnRelationshipElement(column, columnName));
20862                                                                                                }
20863                                                                                        }
20864                                                                                        List<String> names1 = SQLUtil.parseNames(column.getName());
20865                                                                                        if (names.size() == 1 && names1.size() >= 1) {
20866                                                                                                for(String name: names1) {
20867                                                                                                        if (getColumnName(name)
20868                                                                                                                        .equals(getColumnName(column.getName()))) {
20869                                                                                                                relation.addSource(
20870                                                                                                                                new ResultColumnRelationshipElement(column, columnName));
20871                                                                                                        }
20872                                                                                                }
20873                                                                                        }
20874                                                                                }
20875                                                                        }
20876                                                                } else if (table.getAliasClause() != null
20877                                                                                && table.getAliasClause().getColumns() != null) {
20878                                                                        for (k = 0; k < columns.size(); k++) {
20879                                                                                ResultColumn column = columns.get(k);
20880                                                                                List<String> splits = SQLUtil.parseNames(columnName.toString());        
20881                                                                                if ("*".equals(column.getName())) {
20882                                                                                        if (!containsStarColumn(column, columnName)) {
20883                                                                                                column.bindStarLinkColumn(columnName);
20884                                                                                        }
20885                                                                                        relation.addSource(new ResultColumnRelationshipElement(column, columnName));
20886                                                                                } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
20887                                                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)),
20888                                                                                                        DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
20889                                                                                                if (!column.equals(modelObject)) {
20890                                                                                                        relation.addSource(new ResultColumnRelationshipElement(column,
20891                                                                                                                        columnName));
20892                                                                                                }
20893                                                                                                break;
20894                                                                                        }
20895                                                                                } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
20896                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
20897                                                                                        if (!column.equals(modelObject)) {
20898                                                                                                relation.addSource(
20899                                                                                                                new ResultColumnRelationshipElement(column, columnName));
20900                                                                                        }
20901                                                                                        break;
20902                                                                                }
20903                                                                        }
20904                                                                } else if (table.getSubquery() != null || (table.getTableExpr() != null
20905                                                                                && table.getTableExpr().getSubQuery() != null)) {
20906                                                                        TSelectSqlStatement select = table.getSubquery();
20907                                                                        if (select == null) {
20908                                                                                select = table.getTableExpr().getSubQuery();
20909                                                                        }
20910                                                                        if (columnName.getSourceTable() != null) {
20911                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
20912                                                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
20913                                                                                                tableModel);
20914                                                                        } else if (columnName.getObjectToken() != null
20915                                                                                        && !SQLUtil.isEmpty(table.getAliasName())) {
20916                                                                                if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(),
20917                                                                                                table.getAliasName())) {
20918                                                                                        Object tableModel = modelManager.getModel(table);
20919                                                                                        appendResultColumnRelationSource(modelObject, relation, columnIndex,
20920                                                                                                        columnName, tableModel);
20921                                                                                }
20922                                                                        } else if(columns!=null) {
20923                                                                                for (k = 0; k < columns.size(); k++) {
20924                                                                                        ResultColumn column = columns.get(k);
20925                                                                                        List<String> splits = SQLUtil.parseNames(columnName.toString());        
20926                                                                                        if ("*".equals(column.getName())) {
20927                                                                                                if (!containsStarColumn(column, columnName)) {
20928                                                                                                        column.bindStarLinkColumn(columnName);
20929                                                                                                }
20930                                                                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
20931                                                                                        } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
20932                                                                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)),
20933                                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
20934                                                                                                        if (!column.equals(modelObject)) {
20935                                                                                                                relation.addSource(new ResultColumnRelationshipElement(column,
20936                                                                                                                                columnName));
20937                                                                                                        }
20938                                                                                                        break;
20939                                                                                                }
20940                                                                                        } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
20941                                                                                                        DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
20942                                                                                                if (!column.equals(modelObject)) {
20943                                                                                                        relation.addSource(
20944                                                                                                                        new ResultColumnRelationshipElement(column, columnName));
20945                                                                                                }
20946                                                                                                break;
20947                                                                                        }
20948                                                                                }
20949                                                                        }
20950                                                                } else if (table.getOutputMerge() != null) {
20951                                                                        if (columnName.getSourceColumn() != null) {
20952                                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
20953                                                                                if (model instanceof ResultColumn) {
20954                                                                                        ResultColumn resultColumn = (ResultColumn) model;
20955                                                                                        if ("*".equals(resultColumn.getName())
20956                                                                                                        && !containsStarColumn(resultColumn, columnName)) {
20957                                                                                                resultColumn.bindStarLinkColumn(columnName);
20958                                                                                        }
20959                                                                                        relation.addSource(
20960                                                                                                        new ResultColumnRelationshipElement(resultColumn, columnName));
20961                                                                                }
20962                                                                        } else if (columnName.getSourceTable() != null) {
20963                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
20964                                                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
20965                                                                                                tableModel);
20966                                                                        } else if (columnName.getObjectToken() != null
20967                                                                                        && !SQLUtil.isEmpty(table.getAliasName())) {
20968                                                                                if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(),
20969                                                                                                table.getAliasName())) {
20970                                                                                        Object tableModel = modelManager.getModel(table);
20971                                                                                        appendResultColumnRelationSource(modelObject, relation, columnIndex,
20972                                                                                                        columnName, tableModel);
20973                                                                                }
20974                                                                        }
20975                                                                }
20976                                                        }
20977                                                }
20978                                        }
20979                                }
20980                        }
20981                        if (relation.getSources().size() == 0 && isKeyword(columnName)) {
20982                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
20983                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable, columnName, true);
20984                                relation.addSource(new ConstantRelationshipElement(constantColumn));
20985                        }
20986
20987                        if (relation.getSources().size() > 0) {
20988                                for (RelationshipElement<?> sourceItem: relation.getSources()) {
20989                                        Object source = sourceItem.getElement();
20990                                        ImpactRelationship impactRelation = null;
20991                                        if (source instanceof ResultColumn
20992                                                        && !((ResultColumn) source).getResultSet().getRelationRows().getHoldRelations().isEmpty()) {
20993                                                impactRelation = modelFactory.createImpactRelation();
20994                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
20995                                                                ((ResultColumn) source).getResultSet().getRelationRows()));
20996                                                impactRelation.setEffectType(effectType);
20997                                        } else if (source instanceof TableColumn
20998                                                        && !((TableColumn) source).getTable().getRelationRows().getHoldRelations().isEmpty()) {
20999                                                impactRelation = modelFactory.createImpactRelation();
21000                                                impactRelation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(
21001                                                                ((TableColumn) source).getTable().getRelationRows()));
21002                                                impactRelation.setEffectType(effectType);;
21003                                        }
21004
21005                                        if (impactRelation == null) {
21006                                                continue;
21007                                        }
21008
21009                                        Object target = relation.getTarget().getElement();
21010                                        if (target instanceof ResultColumn) {
21011                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21012                                                                ((ResultColumn) target).getResultSet().getRelationRows()));
21013                                        } else if (target instanceof TableColumn) {
21014                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
21015                                                                ((TableColumn) target).getTable().getRelationRows()));
21016                                        }
21017
21018                                        if (impactRelation.getSources().iterator().next().getElement() == impactRelation.getTarget().getElement()) {
21019                                                modelManager.removeRelation(impactRelation);
21020                                        }
21021                                }
21022                        }
21023                }
21024                return relation;
21025        }
21026
21027        private boolean isNotInProcedure(Table table) {
21028        TStoredProcedureSqlStatement stmt = getProcedureParent(stmtStack.peek());
21029                Procedure procedure = this.modelFactory.createProcedure(stmt);
21030                if(procedure!=null && procedure.getName().equals(table.getParent())){
21031                        return false;
21032                }
21033                return true;
21034        }
21035
21036        private boolean hasJoin(TCustomSqlStatement stmt) {
21037                if (stmt.getJoins() == null || stmt.getJoins().size() == 0)
21038                        return false;
21039                if (stmt.getJoins().size() > 1) {
21040                        return true;
21041                }
21042                TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems();
21043                if (joinItems == null || joinItems.size() == 0) {
21044                        return false;
21045                }
21046                return true;
21047        }
21048
21049        private boolean isInQuery(TSelectSqlStatement query, TResultColumn column) {
21050                if(query == null)
21051                        return false;
21052                TResultColumnList columns = query.getResultColumnList();
21053                if (columns != null) {
21054                        for (int i = 0; i < columns.size(); i++) {
21055                                if (columns.getResultColumn(i).equals(column)) {
21056                                        return true;
21057                                }
21058                        }
21059                }
21060                return false;
21061        }
21062
21063        private void appendResultColumnRelationSource(Object modelObject, DataFlowRelationship relation, int columnIndex,
21064                        TObjectName columnName, Object tableModel) {
21065                if (tableModel instanceof Table) {
21066                        Object model = modelManager.getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName));
21067                        if (model instanceof TableColumn) {
21068                                relation.addSource(new TableColumnRelationshipElement((TableColumn) model));
21069                        }
21070                } else if (tableModel instanceof ResultSet) {
21071                        List<ResultColumn> queryColumns = ((ResultSet) tableModel).getColumns();
21072                        boolean flag = false;
21073                        for (int l = 0; l < queryColumns.size(); l++) {
21074                                ResultColumn column = queryColumns.get(l);
21075                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
21076                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
21077                                        if (!column.equals(modelObject)) {
21078                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
21079                                                flag = true;
21080                                        }
21081                                        break;
21082                                }
21083                        }
21084                        if (!flag) {
21085                                for (int l = 0; l < queryColumns.size(); l++) {
21086                                        ResultColumn column = queryColumns.get(l);
21087                                        if ("*".equals(column.getName())) {
21088                                                if (!containsStarColumn(column, columnName)) {
21089                                                        column.bindStarLinkColumn(columnName);
21090                                                }
21091                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
21092                                                flag = true;
21093                                                break;
21094                                        }
21095                                }
21096                        }
21097                        if (!flag && columnIndex < queryColumns.size() && columnIndex != -1) {
21098                                relation.addSource(new ResultColumnRelationshipElement(queryColumns.get(columnIndex), columnName));
21099                        }
21100                }
21101        }
21102
21103        private boolean isApplyJoin(TCustomSqlStatement stmt) {
21104                if (stmt.getJoins() == null || stmt.getJoins().size() == 0)
21105                        return false;
21106                TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems();
21107                if (joinItems == null || joinItems.size() == 0) {
21108                        return false;
21109                }
21110                if (joinItems.getJoinItem(0).getJoinType() == EJoinType.crossapply
21111                                || joinItems.getJoinItem(0).getJoinType() == EJoinType.outerapply)
21112                        return true;
21113                return false;
21114        }
21115
21116        private boolean containsStarColumn(ResultColumn resultColumn, TObjectName columnName) {
21117                String targetColumnName = getColumnName(columnName);
21118                if (resultColumn.hasStarLinkColumn()) {
21119                        return resultColumn.getStarLinkColumns().containsKey(targetColumnName);
21120                }
21121                return false;
21122        }
21123
21124        private void analyzeAggregate(TFunctionCall function, TExpression expr) {
21125                TCustomSqlStatement stmt = stmtStack.peek();
21126                ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
21127                if (resultSet == null) {
21128                        return;
21129                }
21130
21131                if (expr != null) {
21132                        columnsInExpr visitor = new columnsInExpr();
21133                        expr.inOrderTraverse(visitor);
21134                        List<TObjectName> objectNames = visitor.getObjectNames();
21135                        for (int j = 0; j < objectNames.size(); j++) {
21136                                TObjectName columnName = objectNames.get(j);
21137
21138                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
21139                                        continue;
21140                                }
21141
21142                                if (columnName.getColumnNameOnly().startsWith("@")
21143                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
21144                                        continue;
21145                                }
21146
21147                                if (columnName.getColumnNameOnly().startsWith(":")
21148                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
21149                                        continue;
21150                                }
21151
21152                                if(modelManager.getModel(function.getFunctionName()) == null) {
21153                                        continue;
21154                                }
21155                                AbstractRelationship relation = modelFactory.createRecordSetRelation();
21156                                relation.setEffectType(EffectType.function);
21157                                relation.setFunction(function.getFunctionName().toString());
21158                                relation.setTarget(new ResultColumnRelationshipElement(
21159                                                (ResultColumn) modelManager.getModel(function.getFunctionName())));
21160                                TTable table = modelManager.getTable(stmt, columnName);
21161                                if (table != null) {
21162                                        if (modelManager.getModel(table) instanceof Table) {
21163                                                Table tableModel = (Table) modelManager.getModel(table);
21164                                                if (tableModel != null) {
21165                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
21166                                                        if (columnModel != null) {
21167                                                                relation.addSource(
21168                                                                                new TableColumnRelationshipElement(columnModel, columnName.getLocation()));
21169                                                        }
21170                                                }
21171                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
21172                                                Object model = modelManager.getModel(columnName.getSourceColumn());
21173                                                if (model instanceof ResultColumn) {
21174                                                        ResultColumn resultColumn = (ResultColumn) model;
21175                                                        if (resultColumn != null) {
21176                                                                relation.addSource(
21177                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
21178                                                        }
21179                                                }
21180                                        }
21181                                }
21182                        }
21183
21184                        List<TParseTreeNode> functions = visitor.getFunctions();
21185                        for (int j = 0; j < functions.size(); j++) {
21186                                TParseTreeNode functionObj = functions.get(j);
21187                                Object functionModel = modelManager.getModel(functionObj);
21188                                if (functionModel == null) {
21189                                        functionModel = createFunction(functionObj);
21190                                }
21191                                if (functionModel instanceof Function) {
21192                                        AbstractRelationship relation;
21193                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
21194                                                // relation = modelFactory.createDataFlowRelation();
21195                                                relation = modelFactory.createRecordSetRelation();
21196                                        } else {
21197                                                relation = modelFactory.createRecordSetRelation();
21198                                        }
21199                                        relation.setEffectType(EffectType.function);
21200                                        relation.setFunction(function.getFunctionName().toString());
21201                                        relation.setTarget(new ResultColumnRelationshipElement(
21202                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
21203
21204                                        if (functionObj instanceof TFunctionCall) {
21205                                                ResultColumn resultColumn = (ResultColumn) modelManager
21206                                                                .getModel(((TFunctionCall) functionObj).getFunctionName());
21207                                                if (resultColumn != null) {
21208                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn,
21209                                                                        ((TFunctionCall) functionObj).getFunctionName().getLocation());
21210                                                        relation.addSource(element);
21211                                                }
21212                                        }
21213                                        if (functionObj instanceof TCaseExpression) {
21214                                                ResultColumn resultColumn = (ResultColumn) modelManager
21215                                                                .getModel(((TCaseExpression) functionObj).getWhenClauseItemList());
21216                                                if (resultColumn != null) {
21217                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn);
21218                                                        relation.addSource(element);
21219                                                }
21220                                        }
21221                                } else if (functionModel instanceof Table) {
21222                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
21223                                                        function.getFunctionName(), false);
21224                                        AbstractRelationship relation;
21225                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
21226                                                // relation = modelFactory.createDataFlowRelation();
21227                                                relation = modelFactory.createRecordSetRelation();
21228                                        } else {
21229                                                relation = modelFactory.createRecordSetRelation();
21230                                        }
21231                                        relation.setEffectType(EffectType.function);
21232                                        relation.setFunction(function.getFunctionName().toString());
21233                                        relation.setTarget(new ResultColumnRelationshipElement(
21234                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
21235                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
21236                                        relation.addSource(element);
21237                                }
21238                        }
21239                }
21240
21241                if (expr == null || "COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
21242                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())
21243                                        // https://e.gitee.com/gudusoft/issues/list?issue=I4L5EO
21244                                        // 对于非 count() 函数,当有group by clause时, RelationRows 不参与indirect dataflow,
21245                                        // 让位与group by clause中的column.
21246                                        || ((TSelectSqlStatement) stmt).getGroupByClause() == null) {
21247                                TTableList tables = stmt.getTables();
21248                                if (tables != null) {
21249                                        for (int i = 0; i < tables.size(); i++) {
21250                                                TTable table = tables.getTable(i);
21251                                                if (modelManager.getModel(table) == null && table.getSubquery() == null) {
21252                                                        modelFactory.createTable(table);
21253                                                }
21254                                                if (modelManager.getModel(table) instanceof Table) {
21255                                                        Table tableModel = (Table) modelManager.getModel(table);
21256                                                        AbstractRelationship relation;
21257                                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
21258                                                                // relation = modelFactory.createDataFlowRelation();
21259                                                                relation = modelFactory.createRecordSetRelation();
21260                                                        } else {
21261                                                                relation = modelFactory.createRecordSetRelation();
21262                                                        }
21263                                                        relation.setEffectType(EffectType.function);
21264                                                        relation.setFunction(function.getFunctionName().toString());
21265                                                        relation.setTarget(new ResultColumnRelationshipElement(
21266                                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
21267
21268                                                        if (relation instanceof DataFlowRelationship && option.isShowCountTableColumn()) {
21269                                                                List<TExpression> expressions = new ArrayList<TExpression>();
21270                                                                getFunctionExpressions(expressions, new ArrayList<TExpression>(), function);
21271                                                                for (int j = 0; j < expressions.size(); j++) {
21272                                                                        columnsInExpr visitor = new columnsInExpr();
21273                                                                        expressions.get(j).inOrderTraverse(visitor);
21274                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
21275                                                                        if (objectNames != null) {
21276                                                                                for (TObjectName columnName : objectNames) {
21277                                                                                        TTable tempTable = modelManager.getTable(stmt, columnName);
21278                                                                                        if (table.equals(tempTable)) {
21279                                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel,
21280                                                                                                                columnName, false);
21281                                                                                                TableColumnRelationshipElement element = new TableColumnRelationshipElement(
21282                                                                                                                tableColumn);
21283                                                                                                relation.addSource(element);
21284                                                                                        }
21285                                                                                }
21286                                                                        }
21287                                                                }
21288                                                        }
21289                                                        if (relation.getSources().size() == 0) {
21290                                                                RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<TableRelationRows>(
21291                                                                                tableModel.getRelationRows());
21292                                                                relation.addSource(element);
21293                                                        }
21294                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
21295                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(table);
21296                                                        AbstractRelationship relation;
21297                                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
21298                                                                // relation = modelFactory.createDataFlowRelation();
21299                                                                relation = modelFactory.createRecordSetRelation();
21300                                                        } else {
21301                                                                relation = modelFactory.createRecordSetRelation();
21302                                                        }
21303                                                        relation.setEffectType(EffectType.function);
21304                                                        relation.setFunction(function.getFunctionName().toString());
21305                                                        relation.setTarget(new ResultColumnRelationshipElement(
21306                                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
21307                                                        RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<ResultSetRelationRows>(
21308                                                                        tableModel.getRelationRows());
21309                                                        relation.addSource(element);
21310                                                }
21311                                        }
21312                                }
21313                        }
21314
21315                        if (stmt.getWhereClause() == null || stmt.getWhereClause().getCondition() == null) {
21316                                return;
21317                        }
21318
21319                        columnsInExpr visitor = new columnsInExpr();
21320                        stmt.getWhereClause().getCondition().inOrderTraverse(visitor);
21321                        List<TObjectName> objectNames = visitor.getObjectNames();
21322                        for (int j = 0; j < objectNames.size(); j++) {
21323                                TObjectName columnName = objectNames.get(j);
21324                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
21325                                        Variable tableModel;
21326                                        if (columnName.toString().indexOf(".") != -1) {
21327                                                List<String> splits = SQLUtil.parseNames(columnName.toString());
21328                                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
21329                                        } else {
21330                                                tableModel = modelFactory.createVariable(columnName);
21331                                        }
21332                                        tableModel.setCreateTable(true);
21333                                        tableModel.setSubType(SubType.record);
21334                                        TObjectName variableProperties = new TObjectName();
21335                                        variableProperties.setString("*");
21336                                        modelFactory.createTableColumn(tableModel, variableProperties, true);
21337                                }
21338
21339//                              if (columnName.getColumnNameOnly().startsWith("@")
21340//                                              && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
21341//                                      continue;
21342//                              }
21343//
21344//                              if (columnName.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
21345//                                      continue;
21346//                              }
21347
21348                                AbstractRelationship relation = modelFactory.createRecordSetRelation();
21349                                relation.setEffectType(EffectType.function);
21350                                relation.setFunction(function.getFunctionName().toString());
21351                                relation.setTarget(new ResultColumnRelationshipElement(
21352                                                (ResultColumn) modelManager.getModel(function.getFunctionName())));
21353
21354                                TTable table = modelManager.getTable(stmt, columnName);
21355                                if (table != null) {
21356                                        if (modelManager.getModel(table) instanceof Table) {
21357                                                Table tableModel = (Table) modelManager.getModel(table);
21358                                                if (tableModel != null) {
21359                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
21360                                                        if(columnModel == null) {
21361                                                                continue;
21362                                                        }
21363                                                        relation.addSource(
21364                                                                        new TableColumnRelationshipElement(columnModel, columnName.getLocation()));
21365                                                }
21366                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
21367                                                Object model = modelManager.getModel(columnName.getSourceColumn());
21368                                                if (model instanceof ResultColumn) {
21369                                                        ResultColumn resultColumn = (ResultColumn) model;
21370                                                        if (resultColumn != null) {
21371                                                                relation.addSource(
21372                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
21373                                                        }
21374                                                }
21375                                        }
21376                                }
21377                        }
21378                }
21379        }
21380
21381        private void analyzeFilterCondition(Object modelObject, TExpression expr, EJoinType joinType,
21382                        JoinClauseType joinClauseType, EffectType effectType) {
21383                if (expr == null) {
21384                        return;
21385                }
21386
21387                TCustomSqlStatement stmt = stmtStack.peek();
21388
21389                columnsInExpr visitor = new columnsInExpr();
21390                expr.inOrderTraverse(visitor);
21391
21392                List<TObjectName> objectNames = visitor.getObjectNames();
21393                List<TParseTreeNode> functions = visitor.getFunctions();
21394                List<TResultColumn> resultColumns = visitor.getResultColumns();
21395                List<TParseTreeNode> constants = visitor.getConstants();
21396
21397                ImpactRelationship relation = modelFactory.createImpactRelation();
21398                relation.setEffectType(effectType);
21399                relation.setJoinClauseType(joinClauseType);
21400                if (modelObject instanceof ResultColumn) {
21401                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
21402                } else {
21403                        ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
21404                        if (resultSet == null && stmt instanceof TUpdateSqlStatement) {
21405                                resultSet = (ResultSet) modelManager.getModel(stmt);
21406                        }
21407                        if (resultSet == null && stmt instanceof TMergeSqlStatement) {
21408                                TSelectSqlStatement subquery = ((TMergeSqlStatement) stmt).getUsingTable().getSubquery();
21409                                if (subquery != null) {
21410                                        resultSet = (ResultSet) modelManager.getModel(((TMergeSqlStatement) stmt).getUsingTable());
21411                                }
21412                                else {
21413                                        resultSet = modelFactory.createQueryTable(((TMergeSqlStatement) stmt).getUsingTable());
21414                                }
21415                        }
21416                        if (resultSet != null) {
21417                                relation.setTarget(
21418                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
21419                        }
21420                        if (stmt instanceof TDeleteSqlStatement) {
21421                                Table table = (Table) modelManager.getModel(((TDeleteSqlStatement) stmt).getTargetTable());
21422                                if (table != null) {
21423                                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(table.getRelationRows()));
21424                                }
21425                        }
21426                }
21427                if (relation.getTarget() != null) {
21428
21429                        if (constants != null && constants.size() > 0) {
21430                                if (option.isShowConstantTable()) {
21431                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
21432                                        for (int i = 0; i < constants.size(); i++) {
21433                                                TParseTreeNode constant = constants.get(i);
21434                                                if (constant instanceof TConstant) {
21435                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
21436                                                                        (TConstant) constant);
21437                                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
21438                                                } else if (constant instanceof TObjectName) {
21439                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
21440                                                                        (TObjectName) constant, false);
21441                                                        if(constantColumn == null) {
21442                                                                continue;
21443                                                        }
21444                                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
21445                                                }
21446                                        }
21447                                }
21448                        }
21449
21450                        for (int j = 0; j < objectNames.size(); j++) {
21451                                TObjectName columnName = objectNames.get(j);
21452                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
21453                                        Variable variable = modelFactory.createVariable(columnName);
21454                                        variable.setSubType(SubType.record);
21455                                        if (variable.getColumns().isEmpty()) {
21456                                                TObjectName variableProperties = new TObjectName();
21457                                                variableProperties.setString("*");
21458                                                modelFactory.createTableColumn(variable, variableProperties, true);
21459                                        }
21460                                        relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0), columnName.getLocation()));
21461                                        continue;
21462                                }
21463
21464                                if (columnName.getColumnNameOnly().startsWith("@")
21465                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
21466                                        continue;
21467                                }
21468
21469                                if (columnName.getColumnNameOnly().startsWith(":")
21470                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
21471                                        continue;
21472                                }
21473
21474                                TTable table = modelManager.getTable(stmt, columnName);
21475
21476                                if (table == null) {
21477                                        table = columnName.getSourceTable();
21478                                }
21479
21480                                if (table == null && stmt.tables != null) {
21481                                        for (int k = 0; k < stmt.tables.size(); k++) {
21482                                                if (table != null)
21483                                                        break;
21484
21485                                                TTable tTable = stmt.tables.getTable(k);
21486                                                if (tTable.getTableType().name().startsWith("open")) {
21487                                                        continue;
21488                                                } else if (tTable.getLinkedColumns() != null && tTable.getLinkedColumns().size() > 0) {
21489                                                        for (int z = 0; z < tTable.getLinkedColumns().size(); z++) {
21490                                                                TObjectName refer = tTable.getLinkedColumns().getObjectName(z);
21491                                                                if ("*".equals(getColumnName(refer)))
21492                                                                        continue;
21493                                                                if (getColumnName(refer).equals(getColumnName(columnName))) {
21494                                                                        table = tTable;
21495                                                                        break;
21496                                                                }
21497                                                        }
21498                                                } else if (columnName.getTableToken() != null
21499                                                                && (columnName.getTableToken().astext.equalsIgnoreCase(tTable.getName())
21500                                                                                || columnName.getTableToken().astext.equalsIgnoreCase(tTable.getAliasName()))) {
21501                                                        table = tTable;
21502                                                        break;
21503                                                }
21504                                        }
21505
21506                                        if (table == null) {
21507                                                for (int k = 0; k < stmt.tables.size(); k++) {
21508                                                        if (table != null)
21509                                                                break;
21510
21511                                                        TTable tTable = stmt.tables.getTable(k);
21512                                                        Object model = ModelBindingManager.get().getModel(tTable);
21513                                                        if (model instanceof Table) {
21514                                                                Table tableModel = (Table) model;
21515                                                                for (int z = 0; tableModel.getColumns() != null
21516                                                                                && z < tableModel.getColumns().size(); z++) {
21517                                                                        TableColumn refer = tableModel.getColumns().get(z);
21518                                                                        if (getColumnName(refer.getName()).equals(getColumnName(columnName))) {
21519                                                                                table = tTable;
21520                                                                                break;
21521                                                                        }
21522                                                                        if (refer.hasStarLinkColumn()) {
21523                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
21524                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
21525                                                                                                table = tTable;
21526                                                                                                break;
21527                                                                                        }
21528                                                                                }
21529                                                                        }
21530                                                                }
21531                                                        } else if (model instanceof QueryTable) {
21532                                                                QueryTable tableModel = (QueryTable) model;
21533                                                                for (int z = 0; tableModel.getColumns() != null
21534                                                                                && z < tableModel.getColumns().size(); z++) {
21535                                                                        ResultColumn refer = tableModel.getColumns().get(z);
21536                                                                        if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals(
21537                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
21538                                                                                table = tTable;
21539                                                                                break;
21540                                                                        }
21541                                                                        if (refer.hasStarLinkColumn()) {
21542                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
21543                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
21544                                                                                                table = tTable;
21545                                                                                                break;
21546                                                                                        }
21547                                                                                }
21548                                                                        }
21549                                                                }
21550                                                        }
21551                                                }
21552                                        }
21553                                }
21554
21555                                if (table == null && stmt.tables != null && stmt.tables.size() != 0
21556                                                && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) {
21557
21558                                        TObjectName pseudoTableName = new TObjectName();
21559                                        pseudoTableName.setString("pseudo_table_include_orphan_column");
21560                                        Table pseudoTable = modelFactory.createTableByName(pseudoTableName);
21561                                        pseudoTable.setPseudo(true);
21562                                        modelFactory.createTableColumn(pseudoTable, columnName, true);
21563
21564                                        if (isLinkOrphanColumnToFirstTable()) {
21565                                                TTable orphanTable = stmt.tables.getTable(0);
21566                                                table = stmt.tables.getTable(0);
21567                                                Object tableModel = modelManager.getModel(table);
21568                                                if (tableModel == null) {
21569                                                        tableModel = modelFactory.createTable(orphanTable);
21570                                                }
21571                                                if (tableModel instanceof Table) {
21572                                                        modelFactory.createTableColumn((Table) tableModel, columnName, false);
21573                                                        ErrorInfo errorInfo = new ErrorInfo();
21574                                                        errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN);
21575                                                        errorInfo.setErrorMessage("Link orphan column [" + columnName.toString()
21576                                                                        + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]");
21577                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo,
21578                                                                        columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
21579                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo,
21580                                                                        columnName.getEndToken().columnNo + columnName.getEndToken().astext.length(),
21581                                                                        ModelBindingManager.getGlobalHash()));
21582                                                        errorInfo.fillInfo(this);
21583                                                        errorInfos.add(errorInfo);
21584                                                }
21585                                        }
21586                                }
21587
21588                                if (table != null) {
21589                                        if (modelManager.getModel(table) instanceof Table) {
21590                                                Table tableModel = (Table) modelManager.getModel(table);
21591                                                if (tableModel != null) {
21592                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
21593                                                        if(columnModel!=null) {
21594                                                                TableColumnRelationshipElement element = new TableColumnRelationshipElement(columnModel,
21595                                                                                columnName.getLocation());
21596                                                                relation.addSource(element);
21597                                                        }
21598                                                }
21599                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
21600                                                QueryTable tableModel = (QueryTable)modelManager.getModel(table);
21601                                                if (table.getSubquery() != null && table.getSubquery().isCombinedQuery()) {
21602                                                        TSelectSqlStatement subquery = table.getSubquery();
21603                                                        List<ResultSet> resultSets = new ArrayList<ResultSet>();
21604                                                        if (!subquery.getLeftStmt().isCombinedQuery()) {
21605                                                                ResultSet sourceResultSet = (ResultSet) modelManager
21606                                                                                .getModel(subquery.getLeftStmt().getResultColumnList());
21607                                                                resultSets.add(sourceResultSet);
21608                                                        } else {
21609                                                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getLeftStmt());
21610                                                                resultSets.add(sourceResultSet);
21611                                                        }
21612
21613                                                        if (!subquery.getRightStmt().isCombinedQuery()) {
21614                                                                ResultSet sourceResultSet = (ResultSet) modelManager
21615                                                                                .getModel(subquery.getRightStmt().getResultColumnList());
21616                                                                resultSets.add(sourceResultSet);
21617                                                        } else {
21618                                                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getRightStmt());
21619                                                                resultSets.add(sourceResultSet);
21620                                                        }
21621
21622                                                        for (ResultSet sourceResultSet : resultSets) {
21623                                                                if (sourceResultSet != null && columnName.getSourceColumn() != null) {
21624                                                                        for (int k = 0; k < sourceResultSet.getColumns().size(); k++) {
21625                                                                                if (getColumnName(sourceResultSet.getColumns().get(k).getName()).equals(
21626                                                                                                getColumnName(columnName.getSourceColumn().getColumnNameOnly()))) {
21627                                                                                        Set<TObjectName> starLinkColumnSet = sourceResultSet.getColumns().get(k)
21628                                                                                                        .getStarLinkColumns().get(getColumnName(columnName));
21629                                                                                        if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) {
21630                                                                                                ResultColumn column = modelFactory.createResultColumn(sourceResultSet,
21631                                                                                                                starLinkColumnSet.iterator().next(), true);
21632                                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
21633                                                                                        } else {
21634                                                                                                relation.addSource(new ResultColumnRelationshipElement(
21635                                                                                                                sourceResultSet.getColumns().get(k)));
21636                                                                                        }
21637                                                                                }
21638                                                                        }
21639                                                                }
21640                                                        }
21641                                                } else {
21642                                                        Object model = modelManager.getModel(columnName.getSourceColumn());
21643                                                        if (model instanceof ResultColumn) {
21644                                                                ResultColumn resultColumn = (ResultColumn) model;
21645                                                                if (resultColumn != null) {
21646                                                                        if (resultColumn.hasStarLinkColumn()) {
21647                                                                                Set<TObjectName> starLinkColumnSet = resultColumn.getStarLinkColumns()
21648                                                                                                .get(getColumnName(columnName));
21649                                                                                if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) {
21650                                                                                        ResultColumn column = modelFactory.createResultColumn(
21651                                                                                                        resultColumn.getResultSet(), starLinkColumnSet.iterator().next(), true);
21652                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
21653                                                                                } else {
21654                                                                                        resultColumn.bindStarLinkColumn(columnName);
21655                                                                                        ResultColumn column = modelFactory
21656                                                                                                        .createResultColumn(resultColumn.getResultSet(), columnName, true);
21657                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
21658                                                                                }
21659                                                                        } else {
21660                                                                                ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
21661                                                                                                resultColumn, columnName.getLocation());
21662                                                                                relation.addSource(element);
21663                                                                        }
21664                                                                }
21665                                                        }
21666                                                        else{
21667                                                                boolean find = false;
21668                                                                for (int i = 0; i < tableModel.getColumns().size(); i++) {
21669                                                                        ResultColumn resultColumn = tableModel.getColumns().get(i);
21670                                                                        if (DlineageUtil.getIdentifierNormalColumnName(resultColumn.getName()).equals(
21671                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
21672                                                                                ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
21673                                                                                                resultColumn, columnName.getLocation());
21674                                                                                relation.addSource(element);
21675                                                                                find = true;
21676                                                                                break;
21677                                                                        }
21678                                                                        else if (resultColumn.getName().endsWith("*")) {
21679                                                                                resultColumn.bindStarLinkColumn(columnName);
21680                                                                        }
21681                                                                }
21682                                                                if(!find){
21683                                                                        ResultColumn resultColumn = new ResultColumn(tableModel, columnName);
21684                                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
21685                                                                                                resultColumn, columnName.getLocation());
21686                                                                                relation.addSource(element);
21687                                                                }
21688                                                        }
21689                                                }
21690                                        }
21691                                }
21692                        }
21693
21694                        for (int j = 0; j < functions.size(); j++) {
21695                                TParseTreeNode functionObj = functions.get(j);
21696                                Object functionModel = modelManager.getModel(functionObj);
21697                                if (functionModel == null) {
21698                                        functionModel = createFunction(functionObj);
21699                                }
21700                                if (functionModel instanceof Function) {
21701                                        if (functionObj instanceof TFunctionCall) {
21702                                                ResultColumn resultColumn = (ResultColumn) modelManager
21703                                                                .getModel(((TFunctionCall) functionObj).getFunctionName());
21704                                                if (resultColumn != null) {
21705                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn,
21706                                                                        ((TFunctionCall) functionObj).getFunctionName().getLocation());
21707                                                        relation.addSource(element);
21708                                                }
21709                                        }
21710                                        if (functionObj instanceof TCaseExpression) {
21711                                                ResultColumn resultColumn = (ResultColumn) modelManager
21712                                                                .getModel(((TCaseExpression) functionObj).getWhenClauseItemList());
21713                                                if (resultColumn != null) {
21714                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn);
21715                                                        relation.addSource(element);
21716                                                }
21717                                        }
21718                                } else if (functionModel instanceof Table) {
21719                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
21720                                                        ((TFunctionCall) functionObj).getFunctionName(), false);
21721                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
21722                                        relation.addSource(element);
21723                                }
21724                        }
21725
21726                        for (int j = 0; j < resultColumns.size(); j++) {
21727                                TResultColumn resultColumn = resultColumns.get(j);
21728                                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
21729                                        ResultColumn resultColumnModel = (ResultColumn) modelManager.getModel(resultColumn);
21730                                        relation.addSource(new ResultColumnRelationshipElement(resultColumnModel, ESqlClause.selectList));
21731                                }
21732                        }
21733                }
21734
21735                if (isShowJoin() && joinClauseType != null) {
21736                        joinInExpr joinVisitor = new joinInExpr(joinType, joinClauseType, effectType);
21737                        expr.inOrderTraverse(joinVisitor);
21738                }
21739        }
21740
21741        public void dispose() {
21742                appendResultSets.clear();
21743                appendStarColumns.clear();
21744                appendTableStarColumns.clear();
21745                modelManager.DISPLAY_ID.clear();
21746                modelManager.DISPLAY_NAME.clear();
21747                tableIds.clear();
21748                ModelBindingManager.remove();
21749        }
21750
21751        class joinTreatColumnsInExpr implements IExpressionVisitor {
21752
21753                private List<TObjectName> objectNames = new ArrayList<TObjectName>();
21754                
21755                private TTable table;
21756
21757                public joinTreatColumnsInExpr(TTable table) {
21758                        this.table = table;
21759                }
21760
21761                public List<TObjectName> getObjectNames() {
21762                        return objectNames;
21763                }
21764
21765                boolean is_compare_condition(EExpressionType t) {
21766                        return t == EExpressionType.simple_comparison_t;
21767                }
21768
21769                @Override
21770                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
21771                        TExpression expr = (TExpression) pNode;
21772                        if (is_compare_condition(expr.getExpressionType())) {
21773                                TExpression leftExpr = expr.getLeftOperand();
21774                                columnsInExpr leftVisitor = new columnsInExpr();
21775                                leftExpr.inOrderTraverse(leftVisitor);
21776                                List<TObjectName> leftObjectNames = leftVisitor.getObjectNames();
21777
21778                                TExpression rightExpr = expr.getRightOperand();
21779                                columnsInExpr rightVisitor = new columnsInExpr();
21780                                rightExpr.inOrderTraverse(rightVisitor);
21781                                List<TObjectName> rightObjectNames = rightVisitor.getObjectNames();
21782
21783                                if (!leftObjectNames.isEmpty() && !rightObjectNames.isEmpty()) {
21784                                        for (TObjectName column : leftObjectNames) {
21785                                                if (column.getSourceTable() != null && column.getSourceTable().equals(table)) {
21786                                                        objectNames.add(column);
21787                                                        return false;
21788                                                }
21789                                        }
21790                                        for (TObjectName column : rightObjectNames) {
21791                                                if (column.getSourceTable() != null && column.getSourceTable().equals(table)) {
21792                                                        objectNames.add(column);
21793                                                        return false;
21794                                                }
21795                                        }
21796                                }
21797                                return false;
21798                        }
21799                        return true;
21800                }
21801        }
21802        
21803        class columnsInExpr implements IExpressionVisitor {
21804
21805                private List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
21806                private List<TObjectName> objectNames = new ArrayList<TObjectName>();
21807                private List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>();
21808                private List<TResultColumn> resultColumns = new ArrayList<TResultColumn>();
21809                private List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>();
21810                private boolean skipFunction = false;
21811
21812                public void setSkipFunction(boolean skipFunction) {
21813                        this.skipFunction = skipFunction;
21814                }
21815
21816                public List<TParseTreeNode> getFunctions() {
21817                        return functions;
21818                }
21819
21820                public List<TSelectSqlStatement> getSubquerys() {
21821                        return subquerys;
21822                }
21823
21824                public List<TParseTreeNode> getConstants() {
21825                        return constants;
21826                }
21827
21828                public List<TObjectName> getObjectNames() {
21829                        return objectNames;
21830                }
21831
21832                public List<TResultColumn> getResultColumns() {
21833                        return resultColumns;
21834                }
21835
21836                @Override
21837                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
21838                        TExpression lcexpr = (TExpression) pNode;
21839                        if (lcexpr.getExpressionType() == EExpressionType.simple_constant_t) {
21840                                if (lcexpr.getConstantOperand() != null) {
21841                                        if(lcexpr.getConstantOperand().getInt64_expression()!=null 
21842                                                        && lcexpr.getConstantOperand().getInt64_expression().getExpressionType() == EExpressionType.function_t) {
21843                                                lcexpr.getConstantOperand().getInt64_expression().inOrderTraverse(this);
21844                                        }
21845                                        else {
21846                                                constants.add(lcexpr.getConstantOperand());
21847                                        }
21848                                }
21849                        } else if (lcexpr.getExpressionType() == EExpressionType.array_t) {
21850                                if(lcexpr.getObjectOperand()!=null) {
21851                                        TObjectName object = lcexpr.getObjectOperand();
21852                                        objectNames.add(object);
21853                                } else if (lcexpr.getExprList() != null) {
21854                                        for (int j = 0; j < lcexpr.getExprList().size(); j++) {
21855                                                TExpression expr = lcexpr.getExprList().getExpression(j);
21856                                                if (expr != null)
21857                                                        expr.inOrderTraverse(this);
21858                                        }
21859                                }
21860                        } else if (lcexpr.getExpressionType() == EExpressionType.simple_object_name_t) {
21861                                if (lcexpr.getObjectOperand() != null && !(isBuiltInFunctionName(lcexpr.getObjectOperand())
21862                                                && isFromFunction(lcexpr.getObjectOperand()))) {
21863                                        TObjectName object = lcexpr.getObjectOperand();
21864                                        if (object.getDbObjectType() == EDbObjectType.column
21865                                                        || object.getDbObjectType() == EDbObjectType.column_alias
21866                                                        || object.getDbObjectType() == EDbObjectType.alias
21867                                                        || object.getDbObjectType() == EDbObjectType.unknown
21868                                                        || object.getDbObjectType() == EDbObjectType.variable) {
21869                                                objectNames.add(object);
21870                                        } else if (object.getDbObjectType() == EDbObjectType.notAColumn 
21871                                                        || object.getDbObjectType() == EDbObjectType.date_time_part ) {
21872                                                constants.add(object);
21873                                        }
21874                                }
21875                        } else if (lcexpr.getExpressionType() == EExpressionType.between_t) {
21876                                if (lcexpr.getBetweenOperand() != null && lcexpr.getBetweenOperand().getObjectOperand() != null) {
21877                                        TObjectName object = lcexpr.getBetweenOperand().getObjectOperand();
21878                                        if (object.getDbObjectType() == EDbObjectType.column
21879                                                        || object.getDbObjectType() == EDbObjectType.column_alias
21880                                                        || object.getDbObjectType() == EDbObjectType.alias
21881                                                        || object.getDbObjectType() == EDbObjectType.unknown
21882                                                        || object.getDbObjectType() == EDbObjectType.variable) {
21883                                                objectNames.add(object);
21884                                        }
21885                                }
21886                        } else if (lcexpr.getExpressionType() == EExpressionType.object_access_t) {
21887                                if (lcexpr.getObjectAccess() != null) {
21888                                        TObjectNameList objects = lcexpr.getObjectAccess().getAttributes();
21889                                        TFunctionCall function = lcexpr.getObjectAccess().getObjectExpr().getFunctionCall();
21890                                        if (objects != null && function != null) {
21891                                                for (TObjectName object : objects) {
21892                                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
21893                                                        sqlparser.sqltext = "select " + function.getFunctionName().toString() + "."
21894                                                                        + object.getColumnNameOnly() + " from " + function.getFunctionName().toString();
21895                                                        if (sqlparser.parse() == 0) {
21896                                                                TObjectName objectName = sqlparser.sqlstatements.get(0).getResultColumnList()
21897                                                                                .getResultColumn(0).getFieldAttr();
21898                                                                objectNames.add(objectName);
21899                                                        }
21900                                                }
21901                                        }
21902                                }
21903                        } else if (lcexpr.getExpressionType() == EExpressionType.function_t || lcexpr.getExpressionType() == EExpressionType.fieldselection_t) {
21904                                TFunctionCall func = lcexpr.getFunctionCall();
21905                                if (func == null) {
21906                                        return true;
21907                                }
21908                                if (skipFunction) {
21909                                        if (func.getArgs() != null) {
21910                                                for (int k = 0; k < func.getArgs().size(); k++) {
21911                                                        TExpression expr = func.getArgs().getExpression(k);
21912                                                        if (expr != null)
21913                                                                expr.inOrderTraverse(this);
21914                                                }
21915                                        }
21916
21917                                        if (func.getTrimArgument() != null) {
21918                                                TTrimArgument args = func.getTrimArgument();
21919                                                TExpression expr = args.getStringExpression();
21920                                                if (expr != null) {
21921                                                        expr.inOrderTraverse(this);
21922                                                }
21923                                                expr = args.getTrimCharacter();
21924                                                if (expr != null) {
21925                                                        expr.inOrderTraverse(this);
21926                                                }
21927                                        }
21928
21929                                        if (func.getAgainstExpr() != null) {
21930                                                func.getAgainstExpr().inOrderTraverse(this);
21931                                        }
21932//                                      if (func.getBetweenExpr() != null) {
21933//                                              func.getBetweenExpr().inOrderTraverse(this);
21934//                                      }
21935                                        if (func.getExpr1() != null) {
21936                                                func.getExpr1().inOrderTraverse(this);
21937                                        }
21938                                        if (func.getExpr2() != null) {
21939                                                func.getExpr2().inOrderTraverse(this);
21940                                        }
21941                                        if (func.getExpr3() != null) {
21942                                                func.getExpr3().inOrderTraverse(this);
21943                                        }
21944                                        if (func.getParameter() != null) {
21945                                                func.getParameter().inOrderTraverse(this);
21946                                        }
21947                                } else {
21948                                        functions.add(func);
21949                                }
21950
21951                        } else if (lcexpr.getExpressionType() == EExpressionType.case_t) {
21952                                TCaseExpression expr = lcexpr.getCaseExpression();
21953                                if (skipFunction) {
21954                                        TExpression defaultExpr = expr.getElse_expr();
21955                                        if (defaultExpr != null) {
21956                                                defaultExpr.inOrderTraverse(this);
21957                                        }
21958                                        TWhenClauseItemList list = expr.getWhenClauseItemList();
21959                                        for (int i = 0; i < list.size(); i++) {
21960                                                TWhenClauseItem element = (TWhenClauseItem) list.getElement(i);
21961                                                (((TWhenClauseItem) element).getReturn_expr()).inOrderTraverse(this);
21962
21963                                        }
21964                                } else {
21965                                        functions.add(expr);
21966                                }
21967                        } else if (lcexpr.getSubQuery() != null) {
21968                                TSelectSqlStatement select = lcexpr.getSubQuery();
21969                                analyzeSelectStmt(select);
21970                                subquerys.add(select);
21971                                if (select.getResultColumnList() != null && select.getResultColumnList().size() > 0) {
21972                                        for (TResultColumn column : select.getResultColumnList()) {
21973                                                resultColumns.add(column);
21974                                        }
21975                                }
21976                        }
21977                        return true;
21978                }
21979        }
21980
21981        class joinInExpr implements IExpressionVisitor {
21982
21983                private EJoinType joinType;
21984                private JoinClauseType joinClauseType;
21985                private EffectType effectType;
21986
21987                public joinInExpr(EJoinType joinType, JoinClauseType joinClauseType, EffectType effectType) {
21988                        this.joinType = joinType;
21989                        this.joinClauseType = joinClauseType;
21990                        this.effectType = effectType;
21991                }
21992
21993                boolean is_compare_condition(EExpressionType t) {
21994                        return ((t == EExpressionType.simple_comparison_t) || (t == EExpressionType.group_comparison_t)
21995                                        || (t == EExpressionType.in_t) || (t == EExpressionType.pattern_matching_t)
21996                                        || (t == EExpressionType.left_join_t) || (t == EExpressionType.right_join_t));
21997                }
21998
21999                @Override
22000                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
22001                        TExpression expr = (TExpression) pNode;
22002                        if (is_compare_condition(expr.getExpressionType())) {
22003                                TExpression leftExpr = expr.getLeftOperand();
22004                                columnsInExpr leftVisitor = new columnsInExpr();
22005                                leftExpr.inOrderTraverse(leftVisitor);
22006                                List<TObjectName> leftObjectNames = leftVisitor.getObjectNames();
22007                                List<TParseTreeNode> leftObjects = leftVisitor.getFunctions();
22008                                leftObjects.addAll(leftObjectNames);
22009                                
22010                                TExpression rightExpr = expr.getRightOperand();
22011                                columnsInExpr rightVisitor = new columnsInExpr();
22012                                rightExpr.inOrderTraverse(rightVisitor);
22013                                List<TObjectName> rightObjectNames = rightVisitor.getObjectNames();
22014                                List<TParseTreeNode> rightObjects = rightVisitor.getFunctions();
22015                                rightObjects.addAll(rightObjectNames);
22016
22017                                if (!leftObjects.isEmpty() && !rightObjects.isEmpty()) {
22018                                        TCustomSqlStatement stmt = stmtStack.peek();
22019
22020                                        for (int i = 0; i < leftObjects.size(); i++) {
22021                                                TParseTreeNode leftObject = leftObjects.get(i);
22022                                                TTable leftTable = null;
22023                                                TFunctionCall leftFunction = null;
22024                                                TObjectName leftObjectName = null;
22025                                                if (leftObject instanceof TObjectName) {
22026                                                        leftObjectName = (TObjectName)leftObject;
22027
22028                                                        if (leftObjectName.getDbObjectType() == EDbObjectType.variable) {
22029                                                                continue;
22030                                                        }
22031
22032                                                        if (leftObjectName.getColumnNameOnly().startsWith("@")
22033                                                                        && (option.getVendor() == EDbVendor.dbvmssql
22034                                                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
22035                                                                continue;
22036                                                        }
22037
22038                                                        if (leftObjectName.getColumnNameOnly().startsWith(":")
22039                                                                        && (option.getVendor() == EDbVendor.dbvhana
22040                                                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
22041                                                                continue;
22042                                                        }
22043
22044                                                        leftTable = modelManager.getTable(stmt, leftObjectName);
22045
22046                                                        if (leftTable == null) {
22047                                                                leftTable = leftObjectName.getSourceTable();
22048                                                        }
22049
22050                                                        if (leftTable == null) {
22051                                                                leftTable = modelManager.guessTable(stmt, leftObjectName);
22052                                                        }
22053                                                }
22054                                                else if(leftObject instanceof TFunctionCall){
22055                                                        leftFunction = (TFunctionCall)leftObject;
22056                                                }
22057
22058                                                if (leftTable != null || leftFunction != null) {
22059                                                        for (int j = 0; j < rightObjects.size(); j++) {
22060                                                                JoinRelationship joinRelation = modelFactory.createJoinRelation();
22061                                                                joinRelation.setEffectType(effectType);
22062                                                                if (joinType != null) {
22063                                                                        joinRelation.setJoinType(joinType);
22064                                                                } else {
22065                                                                        if (expr.getLeftOperand().isOracleOuterJoin()) {
22066                                                                                joinRelation.setJoinType(right);
22067                                                                        } else if (expr.getRightOperand().isOracleOuterJoin()) {
22068                                                                                joinRelation.setJoinType(EJoinType.left);
22069                                                                        } else if (expr.getExpressionType() == EExpressionType.left_join_t) {
22070                                                                                joinRelation.setJoinType(EJoinType.left);
22071                                                                        } else if (expr.getExpressionType() == EExpressionType.right_join_t) {
22072                                                                                joinRelation.setJoinType(right);
22073                                                                        } else {
22074                                                                                joinRelation.setJoinType(EJoinType.inner);
22075                                                                        }
22076                                                                }
22077
22078                                                                joinRelation.setJoinClauseType(joinClauseType);
22079                                                                joinRelation.setJoinCondition(expr.toString());
22080
22081
22082                                                                if (leftTable != null) {
22083                                                                        if (modelManager.getModel(leftTable) instanceof Table) {
22084                                                                                Table tableModel = (Table) modelManager.getModel(leftTable);
22085                                                                                if (tableModel != null) {
22086                                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel,
22087                                                                                                        leftObjectName, false);
22088                                                                                        if (columnModel != null) {
22089                                                                                                joinRelation.addSource(new TableColumnRelationshipElement(columnModel));
22090                                                                                        }
22091                                                                                }
22092                                                                        } else if (modelManager.getModel(leftTable) instanceof QueryTable) {
22093                                                                                QueryTable table = (QueryTable) modelManager.getModel(leftTable);
22094                                                                                TSelectSqlStatement subquery = table.getTableObject().getSubquery();
22095                                                                                if (subquery != null && subquery.isCombinedQuery()) {
22096                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
22097                                                                                                        leftObjectName);
22098                                                                                        if (resultColumn != null) {
22099                                                                                                joinRelation
22100                                                                                                                .addSource(new ResultColumnRelationshipElement(resultColumn));
22101                                                                                        }
22102                                                                                } else if (leftObjectName.getSourceColumn() != null) {
22103                                                                                        Object model = modelManager.getModel(leftObjectName);
22104                                                                                        if (model == null) {
22105                                                                                                model = modelFactory.createResultColumn(table, leftObjectName);
22106                                                                                        }
22107                                                                                        if (model instanceof ResultColumn) {
22108                                                                                                ResultColumn resultColumn = (ResultColumn) model;
22109                                                                                                if (resultColumn != null) {
22110                                                                                                        joinRelation.addSource(
22111                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
22112                                                                                                }
22113                                                                                        } else if (model instanceof LinkedHashMap) {
22114                                                                                                String columnName = getColumnNameOnly(leftObjectName.toString());
22115                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model;
22116                                                                                                if (resultColumns.containsKey(columnName)) {
22117                                                                                                        ResultColumn resultColumn = resultColumns.get(columnName);
22118                                                                                                        joinRelation.addSource(
22119                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
22120                                                                                                }
22121                                                                                        }
22122                                                                                } else {
22123                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
22124                                                                                                        leftObjectName);
22125                                                                                        if (resultColumn != null) {
22126                                                                                                joinRelation
22127                                                                                                                .addSource(new ResultColumnRelationshipElement(resultColumn));
22128                                                                                        }
22129                                                                                }
22130                                                                        }
22131                                                                }
22132                                                                else if(leftFunction!=null) {
22133                                                                        Object functionObj = createFunction(leftFunction);
22134                                                                        if(functionObj instanceof Function) {
22135                                                                                Function function = (Function)functionObj;
22136                                                                                joinRelation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
22137                                                                        }
22138                                                                }
22139
22140                                                                TParseTreeNode rightObject = rightObjects.get(j);
22141                                                                if(rightObject instanceof TObjectName) {
22142                                                                        TObjectName rightObjectName = (TObjectName)rightObject;
22143
22144                                                                        if (rightObjectName.getDbObjectType() == EDbObjectType.variable) {
22145                                                                                continue;
22146                                                                        }
22147
22148                                                                        if (rightObjectName.getColumnNameOnly().startsWith("@")
22149                                                                                        && (option.getVendor() == EDbVendor.dbvmssql
22150                                                                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
22151                                                                                continue;
22152                                                                        }
22153
22154                                                                        if (rightObjectName.getColumnNameOnly().startsWith(":")
22155                                                                                        && (option.getVendor() == EDbVendor.dbvhana
22156                                                                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
22157                                                                                continue;
22158                                                                        }
22159
22160                                                                        TTable rightTable = modelManager.getTable(stmt, rightObjectName);
22161                                                                        if (rightTable == null) {
22162                                                                                rightTable = rightObjectName.getSourceTable();
22163                                                                        }
22164
22165                                                                        if (rightTable == null) {
22166                                                                                rightTable = modelManager.guessTable(stmt, rightObjectName);
22167                                                                        }
22168
22169                                                                        if (modelManager.getModel(rightTable) instanceof Table) {
22170                                                                                Table tableModel = (Table) modelManager.getModel(rightTable);
22171                                                                                if (tableModel != null) {
22172                                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel,
22173                                                                                                        rightObjectName, false);
22174                                                                                        if(columnModel != null) {
22175                                                                                                joinRelation.setTarget(new TableColumnRelationshipElement(columnModel));
22176                                                                                        }
22177                                                                                }
22178                                                                        } else if (modelManager.getModel(rightTable) instanceof QueryTable) {
22179                                                                                QueryTable table = (QueryTable) modelManager.getModel(rightTable);
22180                                                                                TSelectSqlStatement subquery = table.getTableObject().getSubquery();
22181                                                                                if (subquery != null && subquery.isCombinedQuery()) {
22182                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
22183                                                                                                        rightObjectName);
22184                                                                                        if (resultColumn != null) {
22185                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
22186                                                                                        }
22187                                                                                } else if (rightObjectName.getSourceColumn() != null) {
22188                                                                                        Object model = modelManager.getModel(rightObjectName);
22189                                                                                        if (model == null) {
22190                                                                                                model = modelManager
22191                                                                                                                .getModel(rightObjectName.getSourceColumn());
22192                                                                                        }
22193                                                                                        if (model instanceof ResultColumn) {
22194                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement((ResultColumn)model));
22195                                                                                        }
22196                                                                                        else if (model instanceof LinkedHashMap) {
22197                                                                                                String columnName = getColumnNameOnly(rightObjectName.toString());
22198                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model;
22199                                                                                                if (resultColumns.containsKey(columnName)) {
22200                                                                                                        ResultColumn resultColumn = resultColumns.get(columnName);
22201                                                                                                        joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
22202                                                                                                }
22203                                                                                        }
22204                                                                                } else {
22205                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
22206                                                                                                        rightObjectName);
22207                                                                                        if (resultColumn != null) {
22208                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
22209                                                                                        }
22210                                                                                }
22211                                                                        }
22212                                                                }
22213                                                                else if(rightObject instanceof TFunctionCall) {
22214                                                                        Object functionObj = createFunction(rightObject);
22215                                                                        if(functionObj instanceof Function) {
22216                                                                                Function function = (Function)functionObj;
22217                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(function.getColumns().get(0)));
22218                                                                        }
22219                                                                }
22220                                                        }
22221                                                }
22222                                        }
22223                                }
22224                        }
22225                        return true;
22226                }
22227        }
22228
22229        @Deprecated
22230        public static Dataflow getSqlflowJSONModel(dataflow dataflow) {
22231                EDbVendor vendor = ModelBindingManager.getGlobalVendor();
22232                if(vendor == null) {
22233                        throw new IllegalArgumentException("getSqlflowJSONModel(dataflow dataflow) is deprecated, please call method getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor).");
22234                }
22235                return getSqlflowJSONModel(vendor, dataflow, false);
22236        }
22237
22238        public static Dataflow getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor) {
22239                return getSqlflowJSONModel(vendor, dataflow, false);
22240        }
22241
22242        public static Dataflow getSqlflowJSONModel(EDbVendor vendor, dataflow dataflow, boolean normalizeIdentifier) {
22243                Dataflow model = new Dataflow();
22244                
22245                if (dataflow.getErrors() != null && !dataflow.getErrors().isEmpty()) {
22246                        List<Error> errorList = new ArrayList<Error>();
22247                        for (error error : dataflow.getErrors()) {
22248                                Error err = new Error();
22249                                err.setErrorMessage(error.getErrorMessage());
22250                                err.setErrorType(error.getErrorType());
22251                                err.setCoordinates(Coordinate.parse(error.getCoordinate()));
22252                                err.setFile(err.getFile());
22253                                err.setOriginCoordinates(Coordinate.parse(error.getOriginCoordinate()));
22254                                errorList.add(err);
22255                        }
22256                        model.setErrors(errorList.toArray(new Error[0]));
22257                }
22258
22259                Sqlflow sqlflow = MetadataUtil.convertDataflowToMetadata(vendor, dataflow);
22260                sqlflow.setErrorMessages(null);
22261                model.setDbobjs(sqlflow);
22262                model.setOrientation(dataflow.getOrientation());
22263
22264
22265                List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process> processes = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process>();
22266                if(dataflow.getProcesses()!=null){
22267                        for(process process: dataflow.getProcesses()){
22268                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Process processModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process();
22269                                processModel.setId(process.getId());
22270                                processModel.setName(process.getName());
22271                                processModel.setProcedureId(process.getProcedureId());
22272                                processModel.setProcedureName(process.getProcedureName());
22273                                processModel.setType(process.getType());
22274                                processModel.setCoordinate(process.getCoordinate());
22275                                processModel.setDatabase(process.getDatabase());
22276                                processModel.setSchema(process.getSchema());
22277                                processModel.setServer(process.getServer());
22278                                processModel.setQueryHashId(process.getQueryHashId());
22279                                if (process.getTransforms() != null && !process.getTransforms().isEmpty()) {
22280                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>();
22281                                        for (transform transform : process.getTransforms()) {
22282                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform();
22283                                                item.setCode(transform.getCode());
22284                                                item.setType(transform.getType());
22285                                                item.setCoordinate(transform.getCoordinate(true));
22286                                                transforms.add(item);
22287                                        }
22288                                        processModel.setTransforms(transforms
22289                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0]));
22290                                }
22291                                processes.add(processModel);
22292                        }
22293                }
22294                model.setProcesses(processes.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process[0]));
22295
22296                List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship> relations = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship>();
22297                if (dataflow.getRelationships() != null) {
22298                        for (gudusoft.gsqlparser.dlineage.dataflow.model.xml.relationship relation : dataflow.getRelationships()) {
22299                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship relationModel;
22300                                if (relation.getType().equals("join")) {
22301                                        gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship joinRelationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship();
22302                                        joinRelationModel.setCondition(relation.getCondition());
22303                                        joinRelationModel.setJoinType(relation.getJoinType());
22304                                        joinRelationModel.setClause(relation.getClause());
22305                                        relationModel = joinRelationModel;
22306                                } else {
22307                                        relationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship();
22308                                }
22309
22310                                relationModel.setId(relation.getId());
22311                                relationModel.setProcessId(relation.getProcessId());
22312                                relationModel.setProcessType(relation.getProcessType());
22313                                relationModel.setType(relation.getType());
22314                                relationModel.setEffectType(relation.getEffectType());
22315                                relationModel.setPartition(relation.getPartition());
22316                                relationModel.setFunction(relation.getFunction());
22317                                relationModel.setProcedureId(relation.getProcedureId());
22318                                relationModel.setSqlHash(relation.getSqlHash());
22319                                relationModel.setCondition(relation.getCondition());
22320                                relationModel.setSqlComment(relation.getSqlComment());
22321                                relationModel.setTimestampMax(relation.getTimestampMax());
22322                                relationModel.setTimestampMin(relation.getTimestampMin());
22323                                if (Boolean.TRUE.equals(relation.getBuiltIn())) {
22324                                        relationModel.setBuiltIn(relation.getBuiltIn());
22325                                }
22326                                relationModel.setCallStmt(relation.getCallStmt());
22327                                relationModel.setCallCoordinate(relation.getCallCoordinate());
22328                                
22329                                if (relation.getTarget() != null && relation.getSources() != null && !relation.getSources().isEmpty()) {
22330                                        {
22331                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
22332                                                targetColumn target = relation.getTarget();
22333                                                if (normalizeIdentifier) {
22334                                                        targetModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, target.getColumn()));
22335                                                        targetModel.setParentName(
22336                                                                        SQLUtil.getIdentifierNormalTableName(vendor, target.getParent_name()));
22337                                                        targetModel.setTargetName(
22338                                                                        SQLUtil.getIdentifierNormalColumnName(vendor, target.getTarget_name()));
22339                                                } else {
22340                                                        targetModel.setColumn(target.getColumn());
22341                                                        targetModel.setParentName(target.getParent_name());
22342                                                        targetModel.setTargetName(target.getTarget_name());
22343                                                }
22344                                                targetModel.setId(target.getId());
22345                                                targetModel.setTargetId(target.getTarget_id());
22346                                                targetModel.setParentId(target.getParent_id());
22347                                                targetModel.setCoordinates(Coordinate.parse(target.getCoordinate()));
22348                                                targetModel.setFunction(target.getFunction());
22349                                                targetModel.setType(target.getType());
22350                                                relationModel.setTarget(targetModel);
22351                                        }
22352
22353                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>();
22354                                        for (sourceColumn source : relation.getSources()) {
22355                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
22356                                                if (normalizeIdentifier) {
22357                                                        sourceModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, source.getColumn()));
22358                                                        sourceModel.setParentName(
22359                                                                        SQLUtil.getIdentifierNormalTableName(vendor, source.getParent_name()));
22360                                                        sourceModel.setSourceName(
22361                                                                        SQLUtil.getIdentifierNormalColumnName(vendor, source.getSource_name()));
22362                                                } else {
22363                                                        sourceModel.setColumn(source.getColumn());
22364                                                        sourceModel.setParentName(source.getParent_name());
22365                                                        sourceModel.setSourceName(source.getSource_name());
22366                                                }
22367                                                sourceModel.setColumnType(source.getColumn_type());
22368                                                sourceModel.setId(source.getId());
22369                                                sourceModel.setParentId(source.getParent_id());
22370                                                sourceModel.setSourceId(source.getSource_id());
22371                                                sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate()));
22372                                                sourceModel.setClauseType(source.getClauseType());
22373                                                sourceModel.setType(source.getType());
22374                                                sourceModels.add(sourceModel);
22375                                                if (source.getTransforms() != null && !source.getTransforms().isEmpty()) {
22376                                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>();
22377                                                        for (transform transform : source.getTransforms()) {
22378                                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform();
22379                                                                item.setCode(transform.getCode());
22380                                                                item.setType(transform.getType());
22381                                                                item.setCoordinate(transform.getCoordinate(true));
22382                                                                transforms.add(item);
22383                                                        }
22384                                                        sourceModel.setTransforms(transforms
22385                                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0]));
22386                                                }
22387                                                
22388                                                if (source.getCandidateParents() != null && !source.getCandidateParents().isEmpty()) {
22389                                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable> candidateParents = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable>();
22390                                                        for (candidateTable candidateTable : source.getCandidateParents()) {
22391                                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable();
22392                                                                item.setId(candidateTable.getId());
22393                                                                if (normalizeIdentifier) {
22394                                                                        item.setName(
22395                                                                                        SQLUtil.getIdentifierNormalTableName(vendor, candidateTable.getName()));
22396                                                                } else {
22397                                                                        item.setName(candidateTable.getName());
22398                                                                }
22399                                                                candidateParents.add(item);
22400                                                        }
22401                                                        sourceModel.setCandidateParents(candidateParents
22402                                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable[0]));
22403                                                }
22404                                        }
22405                                        relationModel.setSources(sourceModels
22406                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0]));
22407                                        relations.add(relationModel);
22408                                } else if (relation.getCaller() != null && relation.getCallees() != null
22409                                                && !relation.getCallees().isEmpty()) {
22410                                        {
22411                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
22412                                                targetColumn target = relation.getCaller();
22413                                                if (normalizeIdentifier) {
22414                                                        targetModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, target.getName()));
22415                                                } else {
22416                                                        targetModel.setName(target.getName());
22417                                                }
22418                                                targetModel.setId(target.getId());
22419                                                targetModel.setCoordinates(Coordinate.parse(target.getCoordinate()));
22420                                                targetModel.setType(target.getType());
22421                                                relationModel.setCaller(targetModel);
22422                                        }
22423
22424                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>();
22425                                        for (sourceColumn source : relation.getCallees()) {
22426                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
22427                                                if (normalizeIdentifier) {
22428                                                        sourceModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, source.getName()));
22429                                                } else {
22430                                                        sourceModel.setName(source.getName());
22431                                                }
22432                                                sourceModel.setId(source.getId());
22433                                                sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate()));
22434                                                sourceModel.setType(source.getType());
22435                                                sourceModels.add(sourceModel);
22436                                        }
22437                                        relationModel.setCallees(sourceModels
22438                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0]));
22439                                        relations.add(relationModel);
22440                                }
22441                        }
22442                }
22443                model.setRelationships(relations.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship[0]));
22444                return model;
22445        }
22446
22447        public static String getVersion() {
22448                return "3.1.4";
22449        }
22450
22451        public static String getReleaseDate() {
22452                return "2023-03-04";
22453        }
22454
22455        public static void main(String[] args) {
22456                if (args.length < 1) {
22457                        System.out.println(
22458                                        "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]");
22459                        System.out.println("/f: Option, specify the sql file path to analyze fdd relation.");
22460                        System.out.println("/d: Option, specify the sql directory path to analyze fdd relation.");
22461                        System.out.println("/j: Option, analyze the join relation.");
22462                        System.out.println("/s: Option, simple output, ignore the intermediate results.");
22463                        System.out.println("/i: Option, ignore all result sets.");
22464                        System.out.println("/traceView: Option, analyze the source tables of views.");
22465                        System.out.println("/text: Option, print the plain text format output.");
22466                        System.out.println("/json: Option, print the json format output.");
22467                        System.out.println(
22468                                        "/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");
22469                        System.out.println("/o: Option, write the output stream to the specified file.");
22470                        System.out.println("/log: Option, generate a dataflow.log file to log information.");
22471                        return;
22472                }
22473
22474                File sqlFiles = null;
22475
22476                List<String> argList = Arrays.asList(args);
22477
22478                if (argList.indexOf("/version") != -1) {
22479                        System.out.println("Version: " + DataFlowAnalyzer.getVersion());
22480                        System.out.println("Release Date: " + DataFlowAnalyzer.getReleaseDate());
22481                        return;
22482                }
22483
22484                if (argList.indexOf("/f") != -1 && argList.size() > argList.indexOf("/f") + 1) {
22485                        sqlFiles = new File(args[argList.indexOf("/f") + 1]);
22486                        if (!sqlFiles.exists() || !sqlFiles.isFile()) {
22487                                System.out.println(sqlFiles + " is not a valid file.");
22488                                return;
22489                        }
22490                } else if (argList.indexOf("/d") != -1 && argList.size() > argList.indexOf("/d") + 1) {
22491                        sqlFiles = new File(args[argList.indexOf("/d") + 1]);
22492                        if (!sqlFiles.exists() || !sqlFiles.isDirectory()) {
22493                                System.out.println(sqlFiles + " is not a valid directory.");
22494                                return;
22495                        }
22496                } else {
22497                        System.out.println("Please specify a sql file path or directory path to analyze dlineage.");
22498                        return;
22499                }
22500
22501                EDbVendor vendor = EDbVendor.dbvoracle;
22502
22503                int index = argList.indexOf("/t");
22504
22505                if (index != -1 && args.length > index + 1) {
22506                        vendor = TGSqlParser.getDBVendorByName(args[index + 1]);
22507                }
22508
22509                String outputFile = null;
22510
22511                index = argList.indexOf("/o");
22512
22513                if (index != -1 && args.length > index + 1) {
22514                        outputFile = args[index + 1];
22515                }
22516
22517                FileOutputStream writer = null;
22518                if (outputFile != null) {
22519                        try {
22520                                writer = new FileOutputStream(outputFile);
22521                                System.setOut(new PrintStream(writer));
22522                        } catch (FileNotFoundException e) {
22523                                logger.error("output file is not found.", e);
22524                        }
22525                }
22526
22527                boolean simple = argList.indexOf("/s") != -1;
22528                boolean ignoreResultSets = argList.indexOf("/i") != -1;
22529                boolean showJoin = argList.indexOf("/j") != -1;
22530                boolean textFormat = false;
22531                boolean jsonFormat = false;
22532                if (simple) {
22533                        textFormat = argList.indexOf("/text") != -1;
22534                }
22535
22536                boolean traceView = argList.indexOf("/traceView") != -1;
22537                if (traceView) {
22538                        simple = true;
22539                }
22540
22541                jsonFormat = argList.indexOf("/json") != -1;
22542
22543                DataFlowAnalyzer dlineage = new DataFlowAnalyzer(sqlFiles, vendor, simple);
22544
22545                dlineage.setShowJoin(showJoin);
22546                dlineage.setIgnoreRecordSet(ignoreResultSets);
22547                // dlineage.setShowImplicitSchema(true);
22548
22549                if (simple && !jsonFormat) {
22550                        dlineage.setTextFormat(textFormat);
22551                }
22552
22553                String result = dlineage.generateDataFlow();
22554
22555//              dataflow dataflow = ProcessUtility.generateTableLevelLineage(dlineage, dlineage.getDataFlow());
22556//              System.out.println(result);
22557
22558                if (jsonFormat) {
22559                        // Map jsonResult = new LinkedHashMap();
22560                        Dataflow model = getSqlflowJSONModel(vendor, dlineage.getDataFlow(), true);
22561                        // jsonResult.put("data", BeanUtils.bean2Map(model));
22562                        result = JSON.toJSONString(model);
22563                } else if (traceView) {
22564                        result = dlineage.traceView();
22565                }
22566
22567                if (result != null) {
22568                        System.out.println(result);
22569
22570                        if (writer != null && result.length() < 1024 * 1024) {
22571                                System.err.println(result);
22572                        }
22573                }
22574
22575                try {
22576                        if (writer != null) {
22577                                writer.close();
22578                        }
22579                } catch (IOException e) {
22580                        logger.error("close writer failed.", e);
22581                }
22582
22583                boolean log = argList.indexOf("/log") != -1;
22584
22585                PrintStream systemSteam = System.err;
22586                ByteArrayOutputStream sw = new ByteArrayOutputStream();
22587                PrintStream pw = new PrintStream(sw);
22588                System.setErr(pw);
22589
22590
22591                List<ErrorInfo> errors = dlineage.getErrorMessages();
22592                if (!errors.isEmpty()) {
22593                        System.err.println("Error log:\n");
22594                        for (int i = 0; i < errors.size(); i++) {
22595                                System.err.println(errors.get(i).getErrorMessage());
22596                        }
22597                }
22598
22599                if (sw != null) {
22600                        String errorMessage = sw.toString().trim();
22601                        if (errorMessage.length() > 0) {
22602                                if (log) {
22603                                        try {
22604                                                pw = new PrintStream(new File(".", "dataflow.log"));
22605                                                pw.print(errorMessage);
22606                                        } catch (FileNotFoundException e) {
22607                                                logger.error("error log file is not found.", e);
22608                                        }
22609                                }
22610
22611                                System.setErr(systemSteam);
22612                                System.err.println(errorMessage);
22613                        }
22614                }
22615        }
22616
22617        public List<ErrorInfo> getErrorMessages() {
22618                return errorInfos;
22619        }
22620
22621        public String traceView() {
22622                StringBuilder buffer = new StringBuilder();
22623                dataflow dataflow = this.getDataFlow();
22624                Map<table, Set<table>> traceViewMap = new LinkedHashMap<table, Set<table>>();
22625                if (dataflow != null && dataflow.getViews() != null) {
22626                        List<relationship> relations = dataflow.getRelationships();
22627                        Map<String, table> viewMap = new HashMap<String, table>();
22628                        Map<String, table> tableMap = new HashMap<String, table>();
22629                        for (table view : dataflow.getViews()) {
22630                                viewMap.put(view.getId(), view);
22631                                tableMap.put(view.getId(), view);
22632                        }
22633                        for (table table : dataflow.getTables()) {
22634                                tableMap.put(table.getId(), table);
22635                        }
22636                        for (relationship relation : relations) {
22637                                if (!RelationshipType.fdd.name().equals(relation.getType())) {
22638                                        continue;
22639                                }
22640                                String parentId = relation.getTarget().getParent_id();
22641                                if (viewMap.containsKey(parentId)) {
22642                                        if (!traceViewMap.containsKey(viewMap.get(parentId))) {
22643                                                traceViewMap.put(viewMap.get(parentId), new LinkedHashSet<table>());
22644                                        }
22645
22646                                        for (sourceColumn sourceColumn : relation.getSources()) {
22647                                                traceViewMap.get(viewMap.get(parentId)).add(tableMap.get(sourceColumn.getParent_id()));
22648                                        }
22649                                }
22650                        }
22651
22652                        Map<table, Set<table>> viewTableMap = new LinkedHashMap<table, Set<table>>();
22653                        for (table view : traceViewMap.keySet()) {
22654                                Set<table> tables = new LinkedHashSet<table>();
22655                                traverseViewSourceTables(tables, view, traceViewMap);
22656                                viewTableMap.put(view, tables);
22657                        }
22658
22659                        for (table view : viewTableMap.keySet()) {
22660                                buffer.append(view.getFullName());
22661                                for (table table : viewTableMap.get(view)) {
22662                                        buffer.append(",").append(table.getFullName());
22663                                }
22664                                buffer.append(System.getProperty("line.separator"));
22665                        }
22666                }
22667                return buffer.toString().trim();
22668        }
22669
22670        private void traverseViewSourceTables(Set<table> tables, table view, Map<table, Set<table>> traceViewMap) {
22671                Set<table> sourceTables = traceViewMap.get(view);
22672                for (table sourceTable : sourceTables) {
22673                        if (sourceTable.isTable()) {
22674                                tables.add(sourceTable);
22675                        } else if (sourceTable.isView()) {
22676                                traverseViewSourceTables(tables, sourceTable, traceViewMap);
22677                        }
22678                }
22679        }
22680
22681        protected List<SqlInfo> convertSQL(EDbVendor vendor, String json) {
22682                List<SqlInfo> sqlInfos = new ArrayList<SqlInfo>();
22683                List sqlContents = (List) JSON.parseObject(json);
22684                for (int j = 0; j < sqlContents.size(); j++) {
22685                        Map sqlContent = (Map) sqlContents.get(j);
22686                        String sql = (String) sqlContent.get("sql");
22687                        String fileName = (String) sqlContent.get("fileName");
22688                        String filePath = (String) sqlContent.get("filePath");
22689                        if (sql != null && sql.trim().startsWith("{")) {
22690                                if (sql.indexOf("createdBy") != -1) {
22691                                        if (this.sqlenv == null) {
22692                                                TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(),
22693                                                                option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql);
22694                                                if (sqlenvs != null && sqlenvs.length > 0) {
22695                                                        this.sqlenv = sqlenvs[0];
22696                                                }
22697                                        }
22698                                        if (sql.toLowerCase().indexOf("sqldep") != -1 || sql.toLowerCase().indexOf("grabit") != -1) {
22699                                                Map queryObject = (Map) JSON.parseObject(sql);
22700                                                List querys = (List) queryObject.get("queries");
22701                                                if (querys != null) {
22702                                                        for (int i = 0; i < querys.size(); i++) {
22703                                                                Map object = (Map) querys.get(i);
22704                                                                SqlInfo info = new SqlInfo();
22705                                                                info.setSql(JSON.toJSONString(object));
22706                                                                info.setFileName(fileName);
22707                                                                info.setFilePath(filePath);
22708                                                                info.setOriginIndex(i);
22709                                                                sqlInfos.add(info);
22710                                                        }
22711                                                        queryObject.remove("queries");
22712                                                        SqlInfo info = new SqlInfo();
22713                                                        info.setSql(JSON.toJSONString(queryObject));
22714                                                        info.setFileName(fileName);
22715                                                        info.setFilePath(filePath);
22716                                                        info.setOriginIndex(querys.size());
22717                                                        sqlInfos.add(info);
22718                                                } else {
22719                                                        SqlInfo info = new SqlInfo();
22720                                                        info.setSql(JSON.toJSONString(queryObject));
22721                                                        info.setFileName(fileName);
22722                                                        info.setFilePath(filePath);
22723                                                        info.setOriginIndex(0);
22724                                                        sqlInfos.add(info);
22725                                                }
22726                                        } else if (sql.toLowerCase().indexOf("sqlflow") != -1) {
22727                                                Map sqlflow = (Map) JSON.parseObject(sql);
22728                                                List<Map> servers = (List<Map>) sqlflow.get("servers");
22729                                                if (servers != null) {
22730                                                        for (Map queryObject : servers) {
22731                                                                String name = (String) queryObject.get("name");
22732                                                                String dbVendor = (String) queryObject.get("dbVendor");
22733                                                                List querys = (List) queryObject.get("queries");
22734                                                                if (querys != null) {
22735                                                                        for (int i = 0; i < querys.size(); i++) {
22736                                                                                Map object = (Map) querys.get(i);
22737                                                                                SqlInfo info = new SqlInfo();
22738                                                                                info.setSql(JSON.toJSONString(object));
22739                                                                                info.setFileName(fileName);
22740                                                                                info.setFilePath(filePath);
22741                                                                                info.setOriginIndex(i);
22742                                                                                info.setDbVendor(dbVendor);
22743                                                                                info.setServer(name);
22744                                                                                sqlInfos.add(info);
22745                                                                        }
22746                                                                        queryObject.remove("queries");
22747                                                                        Map serverObject = new IndexedLinkedHashMap();
22748                                                                        serverObject.put("createdBy", sqlflow.get("createdBy"));
22749                                                                        serverObject.put("servers", Arrays.asList(queryObject));
22750                                                                        SqlInfo info = new SqlInfo();
22751                                                                        info.setSql(JSON.toJSONString(serverObject));
22752                                                                        info.setFileName(fileName);
22753                                                                        info.setFilePath(filePath);
22754                                                                        info.setOriginIndex(querys.size());
22755                                                                        info.setDbVendor(dbVendor);
22756                                                                        info.setServer(filePath);
22757                                                                        sqlInfos.add(info);
22758                                                                } else {
22759                                                                        SqlInfo info = new SqlInfo();
22760                                                                        info.setSql(JSON.toJSONString(queryObject));
22761                                                                        info.setFileName(fileName);
22762                                                                        info.setFilePath(filePath);
22763                                                                        info.setOriginIndex(0);
22764                                                                        sqlInfos.add(info);
22765                                                                }
22766                                                        }
22767                                                }
22768                                                
22769                                                List<Map> errorMessages =  (List<Map>) sqlflow.get("errorMessages");
22770                                                if(errorMessages!=null && !errorMessages.isEmpty()) {
22771                                                        for(Map error: errorMessages){
22772                                                                ErrorInfo errorInfo = new ErrorInfo();
22773                                                                errorInfo.setErrorType(ErrorInfo.METADATA_ERROR);
22774                                                                errorInfo.setErrorMessage((String)error.get("errorMessage"));
22775                                                                errorInfo.setFileName(fileName);
22776                                                                errorInfo.setFilePath(filePath);
22777                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L,
22778                                                                                ModelBindingManager.getGlobalHash()));
22779                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L,
22780                                                                                ModelBindingManager.getGlobalHash()));
22781                                                                errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L));
22782                                                                errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L));
22783                                                                metadataErrors.add(errorInfo);
22784                                                        }
22785                                                }
22786                                        }
22787                                }
22788                        } else if (sql != null) {
22789                                SqlInfo info = new SqlInfo();
22790                                info.setSql(sql);
22791                                info.setFileName(fileName);
22792                                info.setFilePath(filePath);
22793                                info.setOriginIndex(0);
22794                                sqlInfos.add(info);
22795                        }
22796                }
22797                return sqlInfos;
22798        }
22799
22800        public void setTextFormat(boolean textFormat) {
22801                option.setTextFormat(textFormat);
22802        }
22803
22804        public boolean isBuiltInFunctionName(TObjectName object) {
22805                if (object == null || object.getGsqlparser() == null)
22806                        return false;
22807                try {
22808                        EDbVendor vendor = object.getGsqlparser().getDbVendor();
22809                        if (vendor == EDbVendor.dbvteradata) {
22810                                boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(object.toString().toUpperCase());
22811                                if (result) {
22812                                        return true;
22813                                }
22814                        }
22815
22816                        List<String> versions = functionChecker.getAvailableDbVersions(vendor);
22817                        if (versions != null && versions.size() > 0) {
22818                                for (int i = 0; i < versions.size(); i++) {
22819                                        boolean result = functionChecker.isBuiltInFunction(object.toString(),
22820                                                        object.getGsqlparser().getDbVendor(), versions.get(i));
22821                                        if (result) {
22822                                                return result;
22823                                        }
22824                                }
22825
22826                                // boolean result =
22827                                // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString());
22828                                // if (result) {
22829                                // return true;
22830                                // }
22831                        }
22832                } catch (Exception e) {
22833                }
22834
22835                return false;
22836        }
22837        
22838        public boolean isBuiltInFunctionName(String functionName) {
22839                if (functionName == null)
22840                        return false;
22841                try {
22842                        EDbVendor vendor = getOption().getVendor();
22843                        if (vendor == EDbVendor.dbvteradata) {
22844                                boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(functionName.toUpperCase());
22845                                if (result) {
22846                                        return true;
22847                                }
22848                        }
22849
22850                        List<String> versions = functionChecker.getAvailableDbVersions(vendor);
22851                        if (versions != null && versions.size() > 0) {
22852                                for (int i = 0; i < versions.size(); i++) {
22853                                        boolean result = functionChecker.isBuiltInFunction(functionName.toUpperCase(),
22854                                                        vendor, versions.get(i));
22855                                        if (result) {
22856                                                return result;
22857                                        }
22858                                }
22859
22860                                // boolean result =
22861                                // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString());
22862                                // if (result) {
22863                                // return true;
22864                                // }
22865                        }
22866                } catch (Exception e) {
22867                }
22868
22869                return false;
22870        }
22871
22872        public boolean isKeyword(TObjectName object) {
22873                if (object == null || object.getGsqlparser() == null)
22874                        return false;
22875                try {
22876                        EDbVendor vendor = object.getGsqlparser().getDbVendor();
22877
22878                        List<String> versions = keywordChecker.getAvailableDbVersions(vendor);
22879                        if (versions != null && versions.size() > 0) {
22880                                for (int i = 0; i < versions.size(); i++) {
22881                                        List<String> segments = SQLUtil.parseNames(object.toString());
22882                                        boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1),
22883                                                        object.getGsqlparser().getDbVendor(), versions.get(i), true);
22884                                        if (result) {
22885                                                return result;
22886                                        }
22887                                }
22888                        }
22889                } catch (Exception e) {
22890                }
22891
22892                return false;
22893        }
22894        
22895        public boolean isKeyword(String objectName) {
22896                if (objectName == null)
22897                        return false;
22898                try {
22899                        EDbVendor vendor = getOption().getVendor();
22900
22901                        List<String> versions = keywordChecker.getAvailableDbVersions(vendor);
22902                        if (versions != null && versions.size() > 0) {
22903                                for (int i = 0; i < versions.size(); i++) {
22904                                        List<String> segments = SQLUtil.parseNames(objectName);
22905                                        boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1),
22906                                                        vendor, versions.get(i), false);
22907                                        if (result) {
22908                                                return result;
22909                                        }
22910                                }
22911                        }
22912                } catch (Exception e) {
22913                }
22914
22915                return false;
22916        }
22917
22918        public boolean isAggregateFunction(TFunctionCall func) {
22919                if (func == null)
22920                        return false;
22921                return Arrays
22922                                .asList(new String[] { "AVG", "COUNT", "MAX", "MIN", "SUM", "COLLECT", "CORR", "COVAR_POP",
22923                                                "COVAR_SAMP", "CUME_DIST", "DENSE_RANK", "FIRST", "GROUP_ID", "GROUPING", "GROUPING_ID", "LAST",
22924                                                "LISTAGG", "MEDIAN", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK",
22925                                                "STATS_BINOMIAL_TEST", "STATS_CROSSTAB", "STATS_F_TEST", "STATS_KS_TEST", "STATS_MODE",
22926                                                "STATS_MW_TEST", "STATS_ONE_WAY_ANOVA", "STATS_WSR_TEST", "STDDEV", "STDDEV_POP", "STDDEV_SAMP",
22927                                                "SYS_XMLAGG", "VAR_ POP", "VAR_ SAMP", "VARI ANCE", "XMLAGG", "ARRAY_AGG" })
22928                                .contains(func.getFunctionName().toString().toUpperCase());
22929        }
22930
22931        public boolean isConstant(TObjectName object) {
22932                if (object == null || object.getGsqlparser() == null)
22933                        return false;
22934                List<String> constants = Arrays.asList(new String[] { "NEXTVAL", "CURRVAL", "SYSDATE", "CENTURY", "YEAR",
22935                                "MONTH", "DAY", "HOUR", "MINUTE", "SECOND" });
22936                List<String> segments = SQLUtil.parseNames(object.toString());
22937                if (segments.size() > 1 && "NEXTVAL".equalsIgnoreCase(object.getColumnNameOnly())
22938                                && option.getVendor() == EDbVendor.dbvoracle) {
22939                        return false;
22940                }
22941                boolean result = constants.indexOf(segments.get(segments.size() - 1).toUpperCase()) != -1;
22942                if (result) {
22943                        return result;
22944                }
22945                if (isKeyword(object)) {
22946                        return true;
22947                }
22948                return false;
22949        }
22950
22951        private Pair3<Long, Long, Integer> convertCoordinate(Pair3<Long, Long, String> position) {
22952                if (ModelBindingManager.getGlobalOption()!=null && ModelBindingManager.getGlobalOption().isIgnoreCoordinate()) {
22953                        return new Pair3<>(-1L, -1L, -1);
22954                }
22955                return new Pair3<Long, Long, Integer>(position.first, position.second,
22956                                ModelBindingManager.getGlobalSqlInfo().getIndexOf(position.third));
22957        }
22958
22959}