001 002package gudusoft.gsqlparser.dlineage; 003 004import gudusoft.gsqlparser.*; 005import gudusoft.gsqlparser.common.structured.StructuredAdapterContext; 006import gudusoft.gsqlparser.common.structured.StructuredDataflowDescriptor; 007import gudusoft.gsqlparser.common.structured.StructuredDataflowRegistry; 008import gudusoft.gsqlparser.common.structured.StructuredFieldBinding; 009import gudusoft.gsqlparser.common.structured.StructuredValueSource; 010import gudusoft.gsqlparser.dlineage.dataflow.listener.DataFlowHandleListener; 011import gudusoft.gsqlparser.dlineage.dataflow.metadata.MetadataReader; 012import gudusoft.gsqlparser.dlineage.dataflow.metadata.grabit.GrabitMetadataAnalyzer; 013import gudusoft.gsqlparser.dlineage.dataflow.metadata.sqldep.SQLDepMetadataAnalyzer; 014import gudusoft.gsqlparser.dlineage.dataflow.metadata.sqlflow.SqlflowMetadataAnalyzer; 015import gudusoft.gsqlparser.dlineage.impl.powerquery.PowerQueryLineageResult; 016import gudusoft.gsqlparser.dlineage.impl.powerquery.TPowerQueryAnalyzer; 017import gudusoft.gsqlparser.dlineage.dataflow.model.*; 018import gudusoft.gsqlparser.dlineage.dataflow.model.Process; 019import gudusoft.gsqlparser.dlineage.dataflow.model.JoinRelationship.JoinClauseType; 020import gudusoft.gsqlparser.dlineage.dataflow.model.json.Coordinate; 021import gudusoft.gsqlparser.dlineage.dataflow.model.json.Dataflow; 022import gudusoft.gsqlparser.dlineage.dataflow.model.json.Error; 023import gudusoft.gsqlparser.dlineage.dataflow.model.xml.*; 024import gudusoft.gsqlparser.dlineage.dataflow.sqlenv.SQLEnvParser; 025import gudusoft.gsqlparser.dlineage.metadata.MetadataUtil; 026import gudusoft.gsqlparser.dlineage.metadata.Sqlflow; 027import gudusoft.gsqlparser.dlineage.util.*; 028import gudusoft.gsqlparser.nodes.TTable; 029import gudusoft.gsqlparser.nodes.*; 030import gudusoft.gsqlparser.nodes.couchbase.TObjectConstruct; 031import gudusoft.gsqlparser.nodes.couchbase.TPair; 032import gudusoft.gsqlparser.nodes.functions.TJsonObjectFunction; 033import gudusoft.gsqlparser.nodes.hive.THiveTransformClause; 034import gudusoft.gsqlparser.nodes.hive.THiveTransformClause.ETransformType; 035import gudusoft.gsqlparser.resolver2.ScopeBuildResult; 036import gudusoft.gsqlparser.resolver2.TSQLResolver2; 037import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType; 038import gudusoft.gsqlparser.sqlenv.TSQLEnv; 039import gudusoft.gsqlparser.sqlenv.TSQLSchema; 040import gudusoft.gsqlparser.sqlenv.TSQLTable; 041import gudusoft.gsqlparser.sqlenv.parser.TJSONSQLEnvParser; 042import gudusoft.gsqlparser.stmt.*; 043import gudusoft.gsqlparser.stmt.db2.TDb2ReturnStmt; 044import gudusoft.gsqlparser.stmt.db2.TDb2SqlVariableDeclaration; 045import gudusoft.gsqlparser.stmt.hive.THiveLoad; 046import gudusoft.gsqlparser.stmt.mssql.*; 047import gudusoft.gsqlparser.stmt.mysql.TLoadDataStmt; 048import gudusoft.gsqlparser.stmt.oracle.*; 049import gudusoft.gsqlparser.stmt.powerquery.TPowerQueryDocumentStmt; 050import gudusoft.gsqlparser.stmt.redshift.TRedshiftCopy; 051import gudusoft.gsqlparser.stmt.redshift.TRedshiftDeclare; 052import gudusoft.gsqlparser.stmt.snowflake.*; 053import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure; 054import gudusoft.gsqlparser.util.*; 055import gudusoft.gsqlparser.util.json.JSON; 056 057import javax.script.ScriptEngine; 058import javax.script.ScriptEngineManager; 059import javax.script.ScriptException; 060import java.io.*; 061import java.util.*; 062import java.util.concurrent.atomic.AtomicInteger; 063import java.util.regex.Matcher; 064import java.util.regex.Pattern; 065import java.util.stream.Collectors; 066 067import static gudusoft.gsqlparser.EJoinType.right; 068 069@SuppressWarnings("rawtypes") 070public class DataFlowAnalyzer implements IDataFlowAnalyzer { 071 072 private static final Logger logger = LoggerFactory.getLogger(DataFlowAnalyzer.class); 073 074 private static final List<String> TERADATA_BUILTIN_FUNCTIONS = Arrays 075 .asList(new String[] { "ACCOUNT", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", 076 "CURRENT_USER", "DATABASE", "DATE", "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", }); 077 078 private static final List<String> CONSTANT_BUILTIN_FUNCTIONS = Arrays.asList(new String[] { "ACCOUNT", 079 "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "DATABASE", "DATE", 080 "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", "GETDATE" }); 081 082 private Stack<TCustomSqlStatement> stmtStack = new Stack<TCustomSqlStatement>(); 083 private List<ResultSet> appendResultSets = new ArrayList<ResultSet>(); 084 private Set<TCustomSqlStatement> accessedStatements = new HashSet<TCustomSqlStatement>(); 085 private Set<TSelectSqlStatement> accessedSubqueries = new HashSet<TSelectSqlStatement>(); 086 private Map<String, TCustomSqlStatement> viewDDLMap = new HashMap<String, TCustomSqlStatement>(); 087 private Map<String, TCustomSqlStatement> procedureDDLMap = new HashMap<String, TCustomSqlStatement>(); 088 private Map<TTable, TObjectNameList> structObjectMap = new HashMap<TTable, TObjectNameList>(); 089 090 private SqlInfo[] sqlInfos; 091 private List<ErrorInfo> errorInfos = new ArrayList<ErrorInfo>(); 092 private IndexedLinkedHashMap<String, List<SqlInfo>> sqlInfoMap = new IndexedLinkedHashMap<String, List<SqlInfo>>(); 093 private TSQLEnv sqlenv = null; 094 private ModelBindingManager modelManager = new ModelBindingManager(); 095 private ModelFactory modelFactory = new ModelFactory(modelManager); 096 private PipelinedFunctionAnalyzer pipelinedAnalyzer; 097 private List<Long> tableIds = new ArrayList<Long>(); 098 private TTableList hiveFromTables; 099 private dataflow dataflow; 100 private String dataflowString; 101 private Option option = new Option(); 102 103 { 104 modelManager.TABLE_COLUMN_ID = option.getStartId(); 105 modelManager.RELATION_ID = option.getStartId(); 106 ModelBindingManager.set(modelManager); 107 ModelBindingManager.setGlobalStmtStack(stmtStack); 108 ModelBindingManager.setGlobalOption(option); 109 ModelBindingManager.setGlobalSqlInfo(sqlInfoMap); 110 } 111 112 private void initPipelinedFunctionAnalyzer() { 113 // Only initialize pipelinedAnalyzer for Oracle 114 if (option.getVendor() == EDbVendor.dbvoracle) 115 { 116 pipelinedAnalyzer = new PipelinedFunctionAnalyzer(modelManager, modelFactory, option); 117 } 118 else{ 119 pipelinedAnalyzer = null; 120 } 121 } 122 123 public DataFlowAnalyzer(String sqlContent, Option option) { 124 SqlInfo[] sqlInfos = new SqlInfo[1]; 125 SqlInfo info = new SqlInfo(); 126 info.setSql(sqlContent); 127 info.setOriginIndex(0); 128 sqlInfos[0] = info; 129 this.option = option; 130 ModelBindingManager.setGlobalOption(this.option); 131 this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 132 } 133 134 public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput, String defaultServer, 135 String defaultDatabase, String defaltSchema) { 136 SqlInfo[] sqlInfos = new SqlInfo[1]; 137 SqlInfo info = new SqlInfo(); 138 info.setSql(sqlContent); 139 info.setOriginIndex(0); 140 sqlInfos[0] = info; 141 option.setVendor(dbVendor); 142 option.setSimpleOutput(simpleOutput); 143 option.setDefaultServer(defaultServer); 144 option.setDefaultDatabase(defaultDatabase); 145 option.setDefaultSchema(defaltSchema); 146 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 147 } 148 149 public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput) { 150 SqlInfo[] sqlInfos = new SqlInfo[1]; 151 SqlInfo info = new SqlInfo(); 152 info.setSql(sqlContent); 153 info.setOriginIndex(0); 154 sqlInfos[0] = info; 155 option.setVendor(dbVendor); 156 option.setSimpleOutput(simpleOutput); 157 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 158 } 159 160 public DataFlowAnalyzer(String[] sqlContents, Option option) { 161 SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length]; 162 for (int i = 0; i < sqlContents.length; i++) { 163 SqlInfo info = new SqlInfo(); 164 info.setSql(sqlContents[i]); 165 info.setOriginIndex(0); 166 sqlInfos[i] = info; 167 } 168 this.option = option; 169 ModelBindingManager.setGlobalOption(this.option); 170 this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 171 } 172 173 public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput, String defaultServer, 174 String defaultDatabase, String defaltSchema) { 175 SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length]; 176 for (int i = 0; i < sqlContents.length; i++) { 177 SqlInfo info = new SqlInfo(); 178 info.setSql(sqlContents[i]); 179 info.setOriginIndex(0); 180 sqlInfos[i] = info; 181 } 182 option.setVendor(dbVendor); 183 option.setSimpleOutput(simpleOutput); 184 option.setDefaultServer(defaultServer); 185 option.setDefaultDatabase(defaultDatabase); 186 option.setDefaultSchema(defaltSchema); 187 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 188 } 189 190 public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput) { 191 SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length]; 192 for (int i = 0; i < sqlContents.length; i++) { 193 SqlInfo info = new SqlInfo(); 194 info.setSql(sqlContents[i]); 195 info.setOriginIndex(0); 196 sqlInfos[i] = info; 197 } 198 option.setVendor(dbVendor); 199 option.setSimpleOutput(simpleOutput); 200 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 201 } 202 203 public DataFlowAnalyzer(SqlInfo[] sqlInfos, Option option) { 204 this.sqlInfos = sqlInfos; 205 this.option = option; 206 ModelBindingManager.setGlobalOption(this.option); 207 } 208 209 public DataFlowAnalyzer(SqlInfo[] sqlInfos, EDbVendor dbVendor, boolean simpleOutput) { 210 this.sqlInfos = sqlInfos; 211 option.setVendor(dbVendor); 212 option.setSimpleOutput(simpleOutput); 213 } 214 215 public DataFlowAnalyzer(File[] sqlFiles, Option option) { 216 SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length]; 217 for (int i = 0; i < sqlFiles.length; i++) { 218 SqlInfo info = new SqlInfo(); 219 info.setSql(SQLUtil.getFileContent(sqlFiles[i])); 220 info.setFileName(sqlFiles[i].getName()); 221 info.setFilePath(sqlFiles[i].getAbsolutePath()); 222 info.setOriginIndex(0); 223 sqlInfos[i] = info; 224 } 225 this.sqlInfos = sqlInfos; 226 this.option = option; 227 ModelBindingManager.setGlobalOption(this.option); 228 } 229 230 public DataFlowAnalyzer(File[] sqlFiles, EDbVendor dbVendor, boolean simpleOutput) { 231 SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length]; 232 for (int i = 0; i < sqlFiles.length; i++) { 233 SqlInfo info = new SqlInfo(); 234 info.setSql(SQLUtil.getFileContent(sqlFiles[i])); 235 info.setFileName(sqlFiles[i].getName()); 236 info.setFilePath(sqlFiles[i].getAbsolutePath()); 237 info.setOriginIndex(0); 238 sqlInfos[i] = info; 239 } 240 this.sqlInfos = sqlInfos; 241 option.setVendor(dbVendor); 242 option.setSimpleOutput(simpleOutput); 243 } 244 245 public DataFlowAnalyzer(File sqlFile, Option option) { 246 File[] children = SQLUtil.listFiles(sqlFile); 247 SqlInfo[] sqlInfos = new SqlInfo[children.length]; 248 for (int i = 0; i < children.length; i++) { 249 SqlInfo info = new SqlInfo(); 250 info.setSql(SQLUtil.getFileContent(children[i])); 251 info.setFileName(children[i].getName()); 252 info.setFilePath(children[i].getAbsolutePath()); 253 info.setOriginIndex(0); 254 sqlInfos[i] = info; 255 } 256 this.sqlInfos = sqlInfos; 257 this.option = option; 258 ModelBindingManager.setGlobalOption(this.option); 259 } 260 261 public DataFlowAnalyzer(File sqlFile, EDbVendor dbVendor, boolean simpleOutput) { 262 File[] children = SQLUtil.listFiles(sqlFile); 263 List<SqlInfo> sqlInfos = new ArrayList<>(); 264 for (int i = 0; i < children.length; i++) { 265 SqlInfo info = new SqlInfo(); 266 info.setSql(SQLUtil.getFileContent(children[i])); 267 if(children[i].getName().toLowerCase().endsWith(".csv")){ 268 if(!MetadataReader.isMetadata(info.getSql())){ 269 continue; 270 } 271 } 272 else if(children[i].getName().toLowerCase().endsWith(".json")){ 273 if (!(MetadataReader.isGrabit(info.getSql()) || MetadataReader.isSqlflow(info.getSql()))){ 274 continue; 275 } 276 } 277 info.setFileName(children[i].getName()); 278 info.setFilePath(children[i].getAbsolutePath()); 279 info.setOriginIndex(0); 280 sqlInfos.add(info); 281 } 282 this.sqlInfos = sqlInfos.toArray(new SqlInfo[0]); 283 option.setVendor(dbVendor); 284 option.setSimpleOutput(simpleOutput); 285 } 286 287 public boolean isIgnoreRecordSet() { 288 return option.isIgnoreRecordSet(); 289 } 290 291 public void setIgnoreRecordSet(boolean ignoreRecordSet) { 292 option.setIgnoreRecordSet(ignoreRecordSet); 293 } 294 295 public boolean isSimpleShowTopSelectResultSet() { 296 return option.isSimpleShowTopSelectResultSet(); 297 } 298 299 public void setSimpleShowTopSelectResultSet(boolean simpleShowTopSelectResultSet) { 300 option.setSimpleShowTopSelectResultSet(simpleShowTopSelectResultSet); 301 } 302 303 public boolean isSimpleShowFunction() { 304 return option.isSimpleShowFunction(); 305 } 306 307 public void setSimpleShowFunction(boolean simpleShowFunction) { 308 option.setSimpleShowFunction(simpleShowFunction); 309 } 310 311 public boolean isShowJoin() { 312 return option.isShowJoin(); 313 } 314 315 public void setShowJoin(boolean showJoin) { 316 option.setShowJoin(showJoin); 317 } 318 319 public void setShowCallRelation(boolean showCallRelation) { 320 option.setShowCallRelation(showCallRelation); 321 } 322 323 public boolean isShowCallRelation() { 324 return option.isShowCallRelation(); 325 } 326 327 public boolean isShowImplicitSchema() { 328 return option.isShowImplicitSchema(); 329 } 330 331 public void setShowImplicitSchema(boolean showImplicitSchema) { 332 option.setShowImplicitSchema(showImplicitSchema); 333 } 334 335 public boolean isShowConstantTable() { 336 return option.isShowConstantTable(); 337 } 338 339 public void setShowConstantTable(boolean showConstantTable) { 340 option.setShowConstantTable(showConstantTable); 341 } 342 343 public boolean isShowCountTableColumn() { 344 return option.isShowCountTableColumn(); 345 } 346 347 public void setShowCountTableColumn(boolean showCountTableColumn) { 348 option.setShowCountTableColumn(showCountTableColumn); 349 } 350 351 public boolean isTransform() { 352 return option.isTransform(); 353 } 354 355 public void setTransform(boolean transform) { 356 option.setTransform(transform); 357 if (option.isTransformCoordinate()) { 358 option.setTransform(true); 359 } 360 } 361 362 public boolean isTransformCoordinate() { 363 return option.isTransformCoordinate(); 364 } 365 366 public void setTransformCoordinate(boolean transformCoordinate) { 367 option.setTransformCoordinate(transformCoordinate); 368 if (transformCoordinate) { 369 option.setTransform(true); 370 } 371 } 372 373 public boolean isLinkOrphanColumnToFirstTable() { 374 return option.isLinkOrphanColumnToFirstTable(); 375 } 376 377 public void setLinkOrphanColumnToFirstTable(boolean linkOrphanColumnToFirstTable) { 378 option.setLinkOrphanColumnToFirstTable(linkOrphanColumnToFirstTable); 379 } 380 381 public boolean isIgnoreTemporaryTable() { 382 return option.isIgnoreTemporaryTable(); 383 } 384 385 public void setIgnoreTemporaryTable(boolean ignoreTemporaryTable) { 386 option.setIgnoreTemporaryTable(ignoreTemporaryTable); 387 } 388 389 public boolean isIgnoreCoordinate() { 390 return option.isIgnoreCoordinate(); 391 } 392 393 public void setIgnoreCoordinate(boolean ignoreCoordinate) { 394 option.setIgnoreCoordinate(ignoreCoordinate); 395 } 396 397 public void setHandleListener(DataFlowHandleListener listener) { 398 option.setHandleListener(listener); 399 } 400 401 public void setSqlEnv(TSQLEnv sqlenv) { 402 this.sqlenv = sqlenv; 403 } 404 405 public void setOption(Option option) { 406 this.option = option; 407 ModelBindingManager.setGlobalOption(this.option); 408 } 409 410 public Option getOption() { 411 return option; 412 } 413 414 public synchronized String chechSyntax() { 415 StringBuilder builder = new StringBuilder(); 416 if (sqlInfos != null) { 417 for (SqlInfo sqlInfo : sqlInfos) { 418 String content = sqlInfo.getSql(); 419 if (content != null && content.indexOf("<dlineage") != -1) { 420 try { 421 XML2Model.loadXML(dataflow.class, content); 422 continue; 423 } catch (Exception e) { 424 builder.append("Parsing dataflow ").append("occurs errors.\n").append(e.getMessage()) 425 .append("\n"); 426 } 427 } 428 if (content != null && content.trim().startsWith("{")) { 429 Map queryObject = (Map) JSON.parseObject(content); 430 content = (String) queryObject.get("sourceCode"); 431 } 432 if (MetadataReader.isMetadata(content)) { 433 continue; 434 } 435 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 436 sqlparser.sqltext = content; 437 int result = sqlparser.parse(); 438 if (result != 0) { 439 builder.append("Parsing sql ").append("occurs errors.\n").append(sqlparser.getErrormessage()) 440 .append("\n"); 441 } 442 } 443 } 444 return builder.toString(); 445 } 446 447 public synchronized String generateDataFlow(boolean withExtraInfo) { 448 if (ModelBindingManager.get() == null) { 449 ModelBindingManager.set(modelManager); 450 } 451 452 initPipelinedFunctionAnalyzer(); 453 454 dataflow = analyzeSqlScript(); 455 456 if (dataflow != null && !withExtraInfo && dataflow.getResultsets() != null) { 457 for (table t : dataflow.getResultsets()) { 458 t.setIsTarget(null); 459 if (t.getColumns() != null) { 460 for (column t1 : t.getColumns()) { 461 t1.setIsFunction(null); 462 } 463 } 464 } 465 } 466 467 if(dataflow!=null && dataflow.getRelationships()!=null && option.getFilterRelationTypes()!=null && !option.getFilterRelationTypes().isEmpty()) { 468 List<relationship> relationships = new ArrayList<relationship>(); 469 for(relationship relationship: dataflow.getRelationships()) { 470 if(option.getFilterRelationTypes().contains(relationship.getType())) { 471 relationships.add(relationship); 472 } 473 } 474 dataflow.setRelationships(relationships); 475 } 476 477 if (option.getHandleListener() != null) { 478 option.getHandleListener().endAnalyze(dataflow); 479 } 480 481 if (option.isOutput()) { 482 if (option.getHandleListener() != null) { 483 option.getHandleListener().startOutputDataFlowXML(); 484 } 485 if (dataflow != null) { 486 if (option.isTextFormat()) { 487 dataflowString = getTextOutput(dataflow); 488 } else { 489 try { 490 dataflowString = XML2Model.saveXML(dataflow); 491 }catch (Exception e){ 492 logger.error("Output dataflow to xml failed.", e); 493 dataflowString = null; 494 } 495 } 496 } 497 if (option.getHandleListener() != null) { 498 option.getHandleListener().endOutputDataFlowXML(dataflowString == null ? 0 : dataflowString.length()); 499 } 500 } 501 502 return dataflowString; 503 } 504 505 private dataflow removeDuplicateColumns(dataflow dataflow) { 506 List<table> tables = new ArrayList<table>(); 507 if (dataflow.getTables() != null) { 508 tables.addAll(dataflow.getTables()); 509 } 510 if (dataflow.getViews() != null) { 511 tables.addAll(dataflow.getViews()); 512 } 513 if (dataflow.getStages() != null) { 514 tables.addAll(dataflow.getStages()); 515 } 516 if (dataflow.getDatasources() != null) { 517 tables.addAll(dataflow.getDatasources()); 518 } 519 if (dataflow.getStreams() != null) { 520 tables.addAll(dataflow.getStreams()); 521 } 522 if (dataflow.getPaths() != null) { 523 tables.addAll(dataflow.getPaths()); 524 } 525 if (dataflow.getVariables() != null) { 526 tables.addAll(dataflow.getVariables()); 527 } 528 if (dataflow.getResultsets() != null) { 529 tables.addAll(dataflow.getResultsets()); 530 } 531 for (table table : tables) { 532 if (table.getColumns() == null) { 533 continue; 534 } 535 Set<String> columnIds = new HashSet<String>(); 536 Iterator<column> iter = table.getColumns().iterator(); 537 while(iter.hasNext()) { 538 column column = iter.next(); 539 String id = column.getId(); 540 if (columnIds.contains(id)) { 541 iter.remove(); 542 } else { 543 columnIds.add(id); 544 } 545 } 546 } 547 return dataflow; 548 } 549 550 public synchronized String generateDataFlow() { 551 return generateDataFlow(false); 552 } 553 554 public synchronized String generateSqlInfos() { 555 return JSON.toJSONString(sqlInfoMap); 556 } 557 558 public Map<String, List<SqlInfo>> getSqlInfos() { 559 return sqlInfoMap; 560 } 561 562 public Map getHashSQLMap() { 563 return modelManager.getHashSQLMap(); 564 } 565 566 public Map getDynamicSQLMap() { 567 return modelManager.getDynamicSQLMap(); 568 } 569 570 /** 571 * @deprecated please use SqlInfoHelper.getSelectedDbObjectInfo 572 */ 573 public DbObjectPosition getSelectedDbObjectInfo(Coordinate start, Coordinate end) { 574 if (start == null || end == null) { 575 throw new IllegalArgumentException("Coordinate can't be null."); 576 } 577 578 String hashCode = start.getHashCode(); 579 580 if (hashCode == null) { 581 throw new IllegalArgumentException("Coordinate hashcode can't be null."); 582 } 583 584 int dbObjectStartLine = (int) start.getX() - 1; 585 int dbObjectStarColumn = (int) start.getY() - 1; 586 int dbObjectEndLine = (int) end.getX() - 1; 587 int dbObjectEndColumn = (int) end.getY() - 1; 588 List<SqlInfo> sqlInfoList; 589 if (hashCode.matches("\\d+")) { 590 sqlInfoList = sqlInfoMap.getValueAtIndex(Integer.valueOf(hashCode)); 591 } else { 592 sqlInfoList = sqlInfoMap.get(hashCode); 593 } 594 for (int j = 0; j < sqlInfoList.size(); j++) { 595 SqlInfo sqlInfo = sqlInfoList.get(j); 596 int startLine = sqlInfo.getLineStart(); 597 int endLine = sqlInfo.getLineEnd(); 598 if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) { 599 DbObjectPosition position = new DbObjectPosition(); 600 position.setFile(sqlInfo.getFileName()); 601 position.setFilePath(sqlInfo.getFilePath()); 602 position.setSql(sqlInfo.getSql()); 603 position.setIndex(sqlInfo.getOriginIndex()); 604 List<Pair<Integer, Integer>> positions = position.getPositions(); 605 positions.add(new Pair<Integer, Integer>( 606 dbObjectStartLine - startLine + sqlInfo.getOriginLineStart() + 1, dbObjectStarColumn + 1)); 607 positions.add(new Pair<Integer, Integer>(dbObjectEndLine - startLine + sqlInfo.getOriginLineStart() + 1, 608 dbObjectEndColumn + 1)); 609 return position; 610 } 611 } 612 return null; 613 } 614 615 public static dataflow mergeTables(dataflow dataflow, Long startId) { 616 return mergeTables(dataflow, startId, new Option()); 617 } 618 619 public static dataflow mergeTables(dataflow dataflow, Long startId, Option option) { 620 List<table> tableCopy = new ArrayList<table>(); 621 List<table> viewCopy = new ArrayList<table>(); 622 List<table> databaseCopy = new ArrayList<table>(); 623 List<table> schemaCopy = new ArrayList<table>(); 624 List<table> stageCopy = new ArrayList<table>(); 625 List<table> dataSourceCopy = new ArrayList<table>(); 626 List<table> streamCopy = new ArrayList<table>(); 627 List<table> fileCopy = new ArrayList<table>(); 628 List<table> variableCopy = new ArrayList<table>(); 629 List<table> cursorCopy = new ArrayList<table>(); 630 List<table> resultSetCopy = new ArrayList<table>(); 631 if (dataflow.getTables() != null) { 632 tableCopy.addAll(dataflow.getTables()); 633 } 634 dataflow.setTables(tableCopy); 635 if (dataflow.getViews() != null) { 636 viewCopy.addAll(dataflow.getViews()); 637 } 638 dataflow.setViews(viewCopy); 639 if (dataflow.getDatabases() != null) { 640 databaseCopy.addAll(dataflow.getDatabases()); 641 } 642 dataflow.setDatabases(databaseCopy); 643 if (dataflow.getSchemas() != null) { 644 schemaCopy.addAll(dataflow.getSchemas()); 645 } 646 dataflow.setSchemas(schemaCopy); 647 if (dataflow.getStages() != null) { 648 stageCopy.addAll(dataflow.getStages()); 649 } 650 dataflow.setStages(stageCopy); 651 if (dataflow.getDatasources() != null) { 652 dataSourceCopy.addAll(dataflow.getDatasources()); 653 } 654 dataflow.setDatasources(dataSourceCopy); 655 if (dataflow.getStreams() != null) { 656 streamCopy.addAll(dataflow.getStreams()); 657 } 658 dataflow.setStreams(streamCopy); 659 if (dataflow.getPaths() != null) { 660 fileCopy.addAll(dataflow.getPaths()); 661 } 662 dataflow.setPaths(fileCopy); 663 if (dataflow.getVariables() != null) { 664 variableCopy.addAll(dataflow.getVariables()); 665 } 666 dataflow.setVariables(variableCopy); 667 if (dataflow.getResultsets() != null) { 668 resultSetCopy.addAll(dataflow.getResultsets()); 669 } 670 dataflow.setResultsets(resultSetCopy); 671 672 Map<String, List<table>> tableMap = new HashMap<String, List<table>>(); 673 Map<String, String> tableTypeMap = new HashMap<String, String>(); 674 Map<String, TMssqlCreateType> mssqlTypeMap = new HashMap<String, TMssqlCreateType>(); 675 Map<String, String> tableIdMap = new HashMap<String, String>(); 676 677 Map<String, List<column>> columnMap = new HashMap<String, List<column>>(); 678 Map<String, Set<String>> tableColumnMap = new HashMap<String, Set<String>>(); 679 Map<String, String> columnIdMap = new HashMap<String, String>(); 680 Map<String, column> columnMergeIdMap = new HashMap<String, column>(); 681 682 List<table> tables = new ArrayList<table>(); 683 tables.addAll(dataflow.getTables()); 684 tables.addAll(dataflow.getViews()); 685 tables.addAll(dataflow.getDatabases()); 686 tables.addAll(dataflow.getSchemas()); 687 tables.addAll(dataflow.getStages()); 688 tables.addAll(dataflow.getDatasources()); 689 tables.addAll(dataflow.getStreams()); 690 tables.addAll(dataflow.getPaths()); 691 tables.addAll(dataflow.getResultsets()); 692 tables.addAll(dataflow.getVariables()); 693 694 Set<String> columnIds = new HashSet<String>(); 695 696 for (table table : tables) { 697 String qualifiedTableName = DlineageUtil.getQualifiedTableName(table); 698 String tableFullName = DlineageUtil.getIdentifierNormalTableName(qualifiedTableName); 699 if ("variable".endsWith(table.getType()) && !SQLUtil.isEmpty(table.getParent())) { 700 tableFullName = table.getParent() + "." + tableFullName; 701 } 702 703 if (!tableMap.containsKey(tableFullName)) { 704 tableMap.put(tableFullName, new ArrayList<table>()); 705 } 706 707 tableMap.get(tableFullName).add(table); 708 709 if (!tableTypeMap.containsKey(tableFullName)) { 710 tableTypeMap.put(tableFullName, table.getType()); 711 } else if ("view".equals(table.getSubType())) { 712 tableTypeMap.put(tableFullName, table.getType()); 713 } else if ("database".equals(table.getSubType())) { 714 tableTypeMap.put(tableFullName, table.getType()); 715 } else if ("schema".equals(table.getSubType())) { 716 tableTypeMap.put(tableFullName, table.getType()); 717 } else if ("stage".equals(table.getSubType())) { 718 tableTypeMap.put(tableFullName, table.getType()); 719 } else if ("sequence".equals(table.getSubType())) { 720 tableTypeMap.put(tableFullName, table.getType()); 721 } else if ("datasource".equals(table.getSubType())) { 722 tableTypeMap.put(tableFullName, table.getType()); 723 } else if ("stream".equals(table.getSubType())) { 724 tableTypeMap.put(tableFullName, table.getType()); 725 } else if ("file".equals(table.getSubType())) { 726 tableTypeMap.put(tableFullName, table.getType()); 727 } else if ("table".equals(tableTypeMap.get(tableFullName))) { 728 tableTypeMap.put(tableFullName, table.getType()); 729 } else if ("variable".equals(tableTypeMap.get(tableFullName))) { 730 tableTypeMap.put(tableFullName, table.getType()); 731 } 732 733 if (table.getColumns() != null) { 734 if (!tableColumnMap.containsKey(tableFullName)) { 735 tableColumnMap.put(tableFullName, new LinkedHashSet<String>()); 736 } 737 for (column column : table.getColumns()) { 738 String columnFullName = tableFullName + "." 739 + (column.getQualifiedTable() != null 740 ? (DlineageUtil.getIdentifierNormalTableName(column.getQualifiedTable()) + ".") 741 : "") 742 + ("false".equals(table.getIsTarget()) ? DlineageUtil.normalizeColumnName(column.getName()) 743 : DlineageUtil.getIdentifierNormalColumnName(column.getName())); 744 745 if (!columnMap.containsKey(columnFullName)) { 746 columnMap.put(columnFullName, new ArrayList<column>()); 747 tableColumnMap.get(tableFullName).add(columnFullName); 748 } 749 750 columnMap.get(columnFullName).add(column); 751 columnIds.add(column.getId()); 752 } 753 } 754 } 755 756 Set<String> relationSourceParentIds = new HashSet<String>(); 757 if (dataflow.getRelationships() != null) { 758 for (relationship rel : dataflow.getRelationships()) { 759 if (rel.getSources() != null) { 760 for (sourceColumn src : rel.getSources()) { 761 if (src.getParent_id() != null) { 762 relationSourceParentIds.add(src.getParent_id()); 763 } 764 } 765 } 766 } 767 } 768 769 Iterator<String> tableNameIter = tableMap.keySet().iterator(); 770 while (tableNameIter.hasNext()) { 771 String tableName = tableNameIter.next(); 772 List<table> tableList = tableMap.get(tableName); 773 table table; 774 if (tableList.size() > 1) { 775 table standardTable = tableList.get(0); 776 // Function允许重名,不做合并处理 777 if (standardTable.isFunction()) { 778 continue; 779 } 780 781 // Variable允许重名,不做合并处理 782 if (standardTable.isVariable()) { 783 continue; 784 } 785 786 // 临时表不做合并处理 787 if(SQLUtil.isTempTable(standardTable)) { 788 continue; 789 } 790 791 String type = tableTypeMap.get(tableName); 792 table = new table(); 793 table.setId(String.valueOf(++startId)); 794 table.setServer(standardTable.getServer()); 795 table.setDatabase(standardTable.getDatabase()); 796 table.setSchema(standardTable.getSchema()); 797 table.setName(standardTable.getName()); 798 table.setDisplayName(standardTable.getDisplayName()); 799 table.setParent(standardTable.getParent()); 800 table.setMore(standardTable.getMore()); 801 table.setColumns(new ArrayList<column>()); 802 table.setSubType(standardTable.getSubType()); 803 Set<String> processIds = new LinkedHashSet<String>(); 804 for (int k = 0; k < tableList.size(); k++) { 805 if (tableList.get(k).getProcessIds() != null) { 806 processIds.addAll(tableList.get(k).getProcessIds()); 807 } 808 } 809 if (!processIds.isEmpty()) { 810 table.setProcessIds(new ArrayList<String>(processIds)); 811 } 812 Set<String> alias = new LinkedHashSet<String>(); 813 for (int k = 0; k < tableList.size(); k++) { 814 if (tableList.get(k).getAlias() != null) { 815 alias.addAll(Arrays.asList(tableList.get(k).getAlias().split("\\s*,\\s*"))); 816 } 817 } 818 if (!alias.isEmpty()) { 819 String aliasString = Arrays.toString(alias.toArray(new String[0])); 820 table.setAlias(aliasString.substring(1, aliasString.length() - 1)); 821 } 822 table.setType(type); 823 for (table item : tableList) { 824 if (!SQLUtil.isEmpty(table.getCoordinate()) && !SQLUtil.isEmpty(item.getCoordinate())) { 825 if (table.getCoordinate().indexOf(item.getCoordinate()) == -1) { 826 table.appendCoordinate(item.getCoordinate()); 827 } 828 } else if (!SQLUtil.isEmpty(item.getCoordinate())) { 829 table.setCoordinate(item.getCoordinate()); 830 } 831 832 if (item.getStarStmt() != null) { 833 table.setStarStmt(item.getStarStmt()); 834 } 835 836 tableIdMap.put(item.getId(), table.getId()); 837 838 if (item.isView()) { 839 dataflow.getViews().remove(item); 840 } else if (item.isDatabaseType()) { 841 dataflow.getDatabases().remove(item); 842 } else if (item.isSchemaType()) { 843 dataflow.getSchemas().remove(item); 844 } else if (item.isStage()) { 845 dataflow.getStages().remove(item); 846 } else if (item.isDataSource()) { 847 dataflow.getDatasources().remove(item); 848 } else if (item.isStream()) { 849 dataflow.getStreams().remove(item); 850 } else if (item.isFile()) { 851 dataflow.getPaths().remove(item); 852 } else if (item.isVariable()) { 853 dataflow.getVariables().remove(item); 854 } else if (item.isTable()) { 855 dataflow.getTables().remove(item); 856 } else if (item.isResultSet()) { 857 dataflow.getResultsets().remove(item); 858 } 859 } 860 861 if (table.isView()) { 862 dataflow.getViews().add(table); 863 } else if (table.isDatabaseType()) { 864 dataflow.getDatabases().add(table); 865 } else if (table.isSchemaType()) { 866 dataflow.getSchemas().add(table); 867 } else if (table.isStage()) { 868 dataflow.getStages().add(table); 869 } else if (table.isDataSource()) { 870 dataflow.getDatasources().add(table); 871 } else if (table.isStream()) { 872 dataflow.getStreams().add(table); 873 } else if (table.isFile()) { 874 dataflow.getPaths().add(table); 875 } else if (table.isVariable()) { 876 dataflow.getVariables().add(table); 877 } else if (table.isResultSet()) { 878 dataflow.getResultsets().add(table); 879 } else { 880 dataflow.getTables().add(table); 881 } 882 } else { 883 table = tableList.get(0); 884 if(Boolean.TRUE.toString().equals(table.getIsDetermined())){ 885 continue; 886 } 887 888 if (option.isIgnoreUnusedSynonym() && SubType.synonym.name().equals(table.getSubType())) { 889 boolean hasSourceRelation = relationSourceParentIds.contains(table.getId()); 890 if (!hasSourceRelation) { 891 dataflow.getTables().remove(table); 892 tableColumnMap.get(tableName).clear(); 893 continue; 894 } 895 } 896 } 897 898 Set<String> columns = tableColumnMap.get(tableName); 899 Iterator<String> columnIter = columns.iterator(); 900 List<column> mergeColumns = new ArrayList<column>(); 901 while (columnIter.hasNext()) { 902 String columnName = columnIter.next(); 903 List<column> columnList = columnMap.get(columnName); 904 List<column> functions = new ArrayList<column>(); 905 for (column t : columnList) { 906 if (Boolean.TRUE.toString().equals(t.getIsFunction())) { 907 functions.add(t); 908 } 909 } 910 if (functions != null && !functions.isEmpty()) { 911 for (column function : functions) { 912 mergeColumns.add(function); 913 columnIdMap.put(function.getId(), function.getId()); 914 columnMergeIdMap.put(function.getId(), function); 915 } 916 917 columnList.removeAll(functions); 918 } 919 if (!columnList.isEmpty()) { 920 column firstColumn = columnList.iterator().next(); 921 if (columnList.size() > 1) { 922 column mergeColumn = new column(); 923 mergeColumn.setId(String.valueOf(++startId)); 924 mergeColumn.setName(firstColumn.getName()); 925 mergeColumn.setDisplayName(firstColumn.getDisplayName()); 926 mergeColumn.setSource(firstColumn.getSource()); 927 mergeColumn.setQualifiedTable(firstColumn.getQualifiedTable()); 928 mergeColumn.setDataType(firstColumn.getDataType()); 929 mergeColumn.setForeignKey(firstColumn.isForeignKey()); 930 mergeColumn.setPrimaryKey(firstColumn.isPrimaryKey()); 931 mergeColumn.setUnqiueKey(firstColumn.isUnqiueKey()); 932 mergeColumn.setIndexKey(firstColumn.isIndexKey()); 933 mergeColumns.add(mergeColumn); 934 for (column item : columnList) { 935 mergeColumn.appendCoordinate(item.getCoordinate()); 936 columnIdMap.put(item.getId(), mergeColumn.getId()); 937 } 938 columnMergeIdMap.put(mergeColumn.getId(), mergeColumn); 939 columnIds.add(mergeColumn.getId()); 940 } else { 941 mergeColumns.add(firstColumn); 942 columnIdMap.put(firstColumn.getId(), firstColumn.getId()); 943 columnMergeIdMap.put(firstColumn.getId(), firstColumn); 944 } 945 } 946 } 947 table.setColumns(mergeColumns); 948 } 949 950 if (dataflow.getRelationships() != null) { 951 Map<String, relationship> mergeRelations = new LinkedHashMap<String, relationship>(); 952 for (int i = 0; i < dataflow.getRelationships().size(); i++) { 953 relationship relation = dataflow.getRelationships().get(i); 954 955 if("crud".equals(relation.getType()) && option.getAnalyzeMode() == AnalyzeMode.crud) { 956 String jsonString = JSON.toJSONString(relation, true); 957 String key = SHA256.getMd5(jsonString); 958 if (!mergeRelations.containsKey(key)) { 959 mergeRelations.put(key, relation); 960 } 961 continue; 962 } 963 964 targetColumn target = relation.getTarget(); 965 if ("call".equals(relation.getType())) { 966 target = relation.getCaller(); 967 } 968 if (target != null && tableIdMap.containsKey(target.getParent_id())) { 969 target.setParent_id(tableIdMap.get(target.getParent_id())); 970 } 971 972 if (columnIdMap.containsKey(target.getId())) { 973 target.setId(columnIdMap.get(target.getId())); 974 target.setCoordinate(columnMergeIdMap.get(target.getId()).getCoordinate()); 975 } 976 else if(option.isIgnoreUnusedSynonym() && EffectType.synonym.name().equals(relation.getEffectType())){ 977 continue; 978 } 979 980 if (!"call".equals(relation.getType()) && !columnIds.contains(target.getId())) { 981 continue; 982 } 983 984 List<sourceColumn> sources = relation.getSources(); 985 if ("call".equals(relation.getType())) { 986 sources = relation.getCallees(); 987 } 988 Set<sourceColumn> sourceSet = new LinkedHashSet<sourceColumn>(); 989 if (sources != null) { 990 for (sourceColumn source : sources) { 991 if (!"call".equals(relation.getType()) && !columnIds.contains(source.getId())) { 992 continue; 993 } 994 if (tableIdMap.containsKey(source.getParent_id())) { 995 source.setParent_id(tableIdMap.get(source.getParent_id())); 996 } 997 if (tableIdMap.containsKey(source.getSource_id())) { 998 source.setSource_id(tableIdMap.get(source.getSource_id())); 999 } 1000 if (columnIdMap.containsKey(source.getId())) { 1001 source.setId(columnIdMap.get(source.getId())); 1002 source.setCoordinate(columnMergeIdMap.get(source.getId()).getCoordinate()); 1003 } 1004 } 1005 1006 sourceSet.addAll(sources); 1007 if ("call".equals(relation.getType())) { 1008 relation.setCallees(new ArrayList<sourceColumn>(sourceSet)); 1009 } else { 1010 relation.setSources(new ArrayList<sourceColumn>(sourceSet)); 1011 } 1012 } 1013 1014 String jsonString = JSON.toJSONString(relation, true); 1015 String key = SHA256.getMd5(jsonString); 1016 if (!mergeRelations.containsKey(key)) { 1017 mergeRelations.put(key, relation); 1018 } 1019 } 1020 1021 dataflow.setRelationships(new ArrayList<relationship>(mergeRelations.values())); 1022 } 1023 1024 tableMap.clear(); 1025 tableTypeMap.clear(); 1026 tableIdMap.clear(); 1027 columnMap.clear(); 1028 tableColumnMap.clear(); 1029 columnIdMap.clear(); 1030 columnMergeIdMap.clear(); 1031 tables.clear(); 1032 return dataflow; 1033 } 1034 1035 public synchronized dataflow getDataFlow() { 1036 if (dataflow != null) { 1037 return dataflow; 1038 } else if (dataflowString != null) { 1039 return XML2Model.loadXML(dataflow.class, dataflowString); 1040 } 1041 return null; 1042 } 1043 1044 List<ErrorInfo> metadataErrors = new ArrayList<>(); 1045 1046 private synchronized dataflow analyzeSqlScript() { 1047 init(); 1048 1049 try { 1050 dataflow dataflow = new dataflow(); 1051 1052 if (sqlInfos != null) { 1053 if (option.getHandleListener() != null) { 1054 if (sqlInfos.length == 1) { 1055 option.getHandleListener().startAnalyze(null, sqlInfos[0].getSql().length(), false); 1056 } else { 1057 option.getHandleListener().startAnalyze(null, sqlInfos.length, true); 1058 } 1059 } 1060 1061 if (sqlenv == null) { 1062 if (option.getHandleListener() != null) { 1063 option.getHandleListener().startParseSQLEnv(); 1064 } 1065 TSQLEnv[] sqlenvs = new SQLEnvParser(option.getDefaultServer(), option.getDefaultDatabase(), 1066 option.getDefaultSchema()).parseSQLEnv(option.getVendor(), sqlInfos); 1067 if (sqlenvs != null && sqlenvs.length > 0) { 1068 sqlenv = sqlenvs[0]; 1069 } 1070 if (option.getHandleListener() != null) { 1071 option.getHandleListener().endParseSQLEnv(); 1072 } 1073 } 1074 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 1075 Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap = new LinkedHashMap<String, Pair3<StringBuilder, AtomicInteger, String>>(); 1076 for (int i = 0; i < sqlInfos.length; i++) { 1077 SqlInfo sqlInfo = sqlInfos[i]; 1078 if (sqlInfo == null) { 1079 sqlInfoMap.put(String.valueOf(i), new ArrayList<SqlInfo>()); 1080 continue; 1081 } 1082 String sql = sqlInfo.getSql(); 1083 if (SQLUtil.isEmpty(sql) && sqlInfo.getFileName() != null 1084 && new File(sqlInfo.getFileName()).exists()) { 1085 sql = SQLUtil.getFileContent(sqlInfo.getFileName()); 1086 } 1087 if (SQLUtil.isEmpty(sql) && sqlInfo.getFilePath() != null 1088 && new File(sqlInfo.getFilePath()).exists()) { 1089 sql = SQLUtil.getFileContent(sqlInfo.getFilePath()); 1090 } 1091 String sqlTrim = null; 1092 if (sql != null) { 1093 sqlTrim = sql.substring(0, Math.min(sql.length(), 512)).trim(); 1094 } 1095 if(sql!=null && sqlTrim.startsWith("<") && sqlTrim.indexOf("<dlineage")!=-1){ 1096 dataflow temp = XML2Model.loadXML(dataflow.class, sql); 1097 if(sqlInfos.length == 1){ 1098 dataflow = temp; 1099 } 1100 else { 1101 if (temp.getTables() != null) { 1102 dataflow.getTables().addAll(temp.getTables()); 1103 } 1104 if (temp.getViews() != null) { 1105 dataflow.getViews().addAll(temp.getViews()); 1106 } 1107 if (temp.getResultsets() != null) { 1108 dataflow.getResultsets().addAll(temp.getResultsets()); 1109 } 1110 if (temp.getRelationships() != null) { 1111 dataflow.getRelationships().addAll(temp.getRelationships()); 1112 } 1113 if (temp.getErrors() != null) { 1114 dataflow.getErrors().addAll(temp.getErrors()); 1115 } 1116 } 1117 } 1118 else if (sql != null && sqlTrim.startsWith("{")) { 1119 EDbVendor vendor = SQLUtil.isEmpty(sqlInfo.getDbVendor()) ? option.getVendor() 1120 : EDbVendor.valueOf(sqlInfo.getDbVendor()); 1121 TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(), 1122 option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql); 1123 if (sqlenvs != null && sqlenvs.length > 0) { 1124 if (sqlenv == null) { 1125 sqlenv = sqlenvs[0]; 1126 } else { 1127 sqlenv = SQLEnvParser.mergeSQLEnv(Arrays.asList(sqlenv, sqlenvs[0])); 1128 } 1129 } 1130 if (sqlenv != null) { 1131 if (MetadataReader.isGrabit(sql) || MetadataReader.isSqlflow(sql)) { 1132 String hash = SHA256.getMd5(sql); 1133 String fileHash = SHA256.getMd5(hash); 1134 if (!sqlInfoMap.containsKey(fileHash)) { 1135 sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>()); 1136 sqlInfoMap.get(fileHash).add(sqlInfo); 1137 } 1138 ModelBindingManager.setGlobalHash(fileHash); 1139 dataflow temp = null; 1140 1141 if (MetadataReader.isGrabit(sql)) { 1142 temp = new GrabitMetadataAnalyzer().analyzeMetadata(option.getVendor(), sql); 1143 } else { 1144 temp = new SqlflowMetadataAnalyzer(sqlenv).analyzeMetadata(option.getVendor(), sql); 1145 } 1146// if (temp.getPackages() != null) { 1147// dataflow.getPackages().addAll(temp.getPackages()); 1148// } 1149// if (temp.getProcedures() != null) { 1150// dataflow.getProcedures().addAll(temp.getProcedures()); 1151// } 1152 if (temp.getTables() != null) { 1153 dataflow.getTables().addAll(temp.getTables()); 1154 } 1155 if (temp.getViews() != null) { 1156 dataflow.getViews().addAll(temp.getViews()); 1157 } 1158 if (temp.getResultsets() != null) { 1159 dataflow.getResultsets().addAll(temp.getResultsets()); 1160 } 1161 if (temp.getRelationships() != null) { 1162 dataflow.getRelationships().addAll(temp.getRelationships()); 1163 } 1164 if (temp.getErrors() != null) { 1165 dataflow.getErrors().addAll(temp.getErrors()); 1166 } 1167 if (sql.indexOf("createdBy") != -1) { 1168 if (sql.toLowerCase().indexOf("sqldep") != -1 1169 || sql.toLowerCase().indexOf("grabit") != -1) { 1170 Map jsonObject = (Map) JSON.parseObject(sql); 1171 List<Map> queries = (List<Map>) jsonObject.get("queries"); 1172 if (queries != null) { 1173 for (int j = 0; j < queries.size(); j++) { 1174 Map queryObject = queries.get(j); 1175 appendSqlInfo(databaseMap, j, sqlInfo, queryObject); 1176 } 1177 } 1178 } else if (sql.toLowerCase().indexOf("sqlflow") != -1) { 1179 Map sqlflow = (Map) JSON.parseObject(sql); 1180 List<Map> servers = (List<Map>) sqlflow.get("servers"); 1181 if (servers != null) { 1182 for (Map serverObject : servers) { 1183 List<Map> queries = (List<Map>) serverObject.get("queries"); 1184 if (queries != null) { 1185 for (int j = 0; j < queries.size(); j++) { 1186 Map queryObject = queries.get(j); 1187 appendSqlInfo(databaseMap, j, sqlInfo, queryObject); 1188 } 1189 } 1190 } 1191 } 1192 List<Map> errorMessages = (List<Map>) sqlflow.get("errorMessages"); 1193 if(errorMessages!=null && !errorMessages.isEmpty()) { 1194 for(Map error: errorMessages){ 1195 ErrorInfo errorInfo = new ErrorInfo(); 1196 errorInfo.setErrorType(ErrorInfo.METADATA_ERROR); 1197 errorInfo.setErrorMessage((String)error.get("errorMessage")); 1198 errorInfo.setFileName(sqlInfo.getFileName()); 1199 errorInfo.setFilePath(sqlInfo.getFilePath()); 1200 errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L, 1201 ModelBindingManager.getGlobalHash())); 1202 errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L, 1203 ModelBindingManager.getGlobalHash())); 1204 errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L)); 1205 errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L)); 1206 metadataErrors.add(errorInfo); 1207 } 1208 } 1209 } 1210 } 1211 } else { 1212 Map queryObject = (Map) JSON.parseObject(sql); 1213 appendSqlInfo(databaseMap, i, sqlInfo, queryObject); 1214 } 1215 } else { 1216 Map queryObject = (Map) JSON.parseObject(sql); 1217 appendSqlInfo(databaseMap, i, sqlInfo, queryObject); 1218 } 1219 } else { 1220 ModelBindingManager.removeGlobalDatabase(); 1221 ModelBindingManager.removeGlobalSchema(); 1222 ModelBindingManager.removeGlobalHash(); 1223 1224 String content = sql; 1225 1226 if (content == null) { 1227 continue; 1228 } 1229 1230 String delimiterChar = String.valueOf(sqlparser.getDelimiterChar()); 1231 1232 if (sqlInfos.length > 1) { 1233 String endTrim = SQLUtil.endTrim(content); 1234 if (endTrim.endsWith(delimiterChar) || endTrim.endsWith(";")) { 1235 content += "\n"; 1236 } else if (option.getVendor() == EDbVendor.dbvredshift 1237 || option.getVendor() == EDbVendor.dbvgaussdb 1238 || option.getVendor() == EDbVendor.dbvedb 1239 || option.getVendor() == EDbVendor.dbvpostgresql 1240 || option.getVendor() == EDbVendor.dbvmysql 1241 || option.getVendor() == EDbVendor.dbvteradata) { 1242 content += ("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n"); 1243 } else { 1244 content = endTrim + ";" + "\n"; 1245 } 1246 } 1247 1248 sqlInfo.setSql(content); 1249 1250 if (MetadataReader.isMetadata(content)) { 1251 String hash = SHA256.getMd5(content); 1252 ModelBindingManager.setGlobalHash(hash); 1253 dataflow temp = new SQLDepMetadataAnalyzer().analyzeMetadata(option.getVendor(), content); 1254 if (temp.getProcedures() != null) { 1255 dataflow.getProcedures().addAll(temp.getProcedures()); 1256 } 1257 if (temp.getTables() != null) { 1258 dataflow.getTables().addAll(temp.getTables()); 1259 } 1260 if (temp.getViews() != null) { 1261 dataflow.getViews().addAll(temp.getViews()); 1262 } 1263 if (temp.getResultsets() != null) { 1264 dataflow.getResultsets().addAll(temp.getResultsets()); 1265 } 1266 if (temp.getRelationships() != null) { 1267 dataflow.getRelationships().addAll(temp.getRelationships()); 1268 } 1269 if (temp.getErrors() != null) { 1270 dataflow.getErrors().addAll(temp.getErrors()); 1271 } 1272 String fileHash = SHA256.getMd5(hash); 1273 if (!sqlInfoMap.containsKey(fileHash)) { 1274 sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>()); 1275 sqlInfoMap.get(fileHash).add(sqlInfo); 1276 } 1277 } else { 1278 String sqlHash = SHA256.getMd5(content); 1279 String fileHash = SHA256.getMd5(sqlHash); 1280 if (!sqlInfoMap.containsKey(fileHash)) { 1281 sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>()); 1282 } 1283 1284 String database = TSQLEnv.DEFAULT_DB_NAME; 1285 String schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 1286 if (sqlenv != null) { 1287 database = sqlenv.getDefaultCatalogName(); 1288 if (database == null) { 1289 database = TSQLEnv.DEFAULT_DB_NAME; 1290 } 1291 schema = sqlenv.getDefaultSchemaName(); 1292 if (schema == null) { 1293 schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 1294 } 1295 } 1296 1297 boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor()); 1298 boolean supportSchema = TSQLEnv.supportSchema(option.getVendor()); 1299 StringBuilder builder = new StringBuilder(); 1300 if (supportCatalog) { 1301 builder.append(database); 1302 } 1303 if (supportSchema) { 1304 if (builder.length() > 0) { 1305 builder.append("."); 1306 } 1307 builder.append(schema); 1308 } 1309 String group = builder.toString(); 1310 SqlInfo sqlInfoItem = new SqlInfo(); 1311 sqlInfoItem.setFileName(sqlInfo.getFileName()); 1312 sqlInfoItem.setFilePath(sqlInfo.getFilePath()); 1313 sqlInfoItem.setSql(sqlInfo.getSql()); 1314 sqlInfoItem.setOriginIndex(0); 1315 sqlInfoItem.setOriginLineStart(0); 1316 int lineEnd = sqlInfo.getSql().split("\n").length - 1; 1317 sqlInfoItem.setOriginLineEnd(lineEnd); 1318 sqlInfoItem.setIndex(0); 1319 sqlInfoItem.setLineStart(0); 1320 sqlInfoItem.setLineEnd(lineEnd); 1321 sqlInfoItem.setHash(SHA256.getMd5(sqlHash)); 1322 sqlInfoItem.setGroup(group); 1323 sqlInfoMap.get(fileHash).add(sqlInfoItem); 1324 if (!databaseMap.containsKey(sqlHash)) { 1325 databaseMap.put(sqlHash, new Pair3<StringBuilder, AtomicInteger, String>( 1326 new StringBuilder(), new AtomicInteger(), group)); 1327 } 1328 databaseMap.get(sqlHash).first.append(sqlInfoItem.getSql()); 1329 databaseMap.get(sqlHash).second.incrementAndGet(); 1330 } 1331 } 1332 } 1333 1334 boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor()); 1335 boolean supportSchema = TSQLEnv.supportSchema(option.getVendor()); 1336 1337 Iterator<String> schemaIter = databaseMap.keySet().iterator(); 1338 while (schemaIter.hasNext()) { 1339 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 1340 break; 1341 } 1342 String key = schemaIter.next(); 1343 String group = databaseMap.get(key).third; 1344 String[] split = SQLUtil.parseNames(group).toArray(new String[0]); 1345 1346 ModelBindingManager.removeGlobalDatabase(); 1347 ModelBindingManager.removeGlobalSchema(); 1348 ModelBindingManager.removeGlobalSQLEnv(); 1349 ModelBindingManager.removeGlobalHash(); 1350 1351 String defaultDatabase = null; 1352 String defaultSchema = null; 1353 if(sqlenv!=null){ 1354 defaultDatabase = sqlenv.getDefaultCatalogName(); 1355 defaultSchema = sqlenv.getDefaultSchemaName(); 1356 } 1357 if (supportCatalog && supportSchema) { 1358 if (split.length >= 2) { 1359 if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 2])) { 1360 ModelBindingManager.setGlobalDatabase(split[split.length - 2]); 1361 sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase()); 1362 } 1363 } 1364 if (split.length >= 1) { 1365 if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) { 1366 ModelBindingManager.setGlobalSchema(split[split.length - 1]); 1367 sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema()); 1368 } 1369 } 1370 } else if (supportCatalog) { 1371 if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 1])) { 1372 ModelBindingManager.setGlobalDatabase(split[split.length - 1]); 1373 sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase()); 1374 } 1375 } else if (supportSchema) { 1376 if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) { 1377 ModelBindingManager.setGlobalSchema(split[split.length - 1]); 1378 sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema()); 1379 } 1380 } 1381 if (option.getHandleListener() != null) { 1382 option.getHandleListener().startParse(null, databaseMap.get(key).first.toString()); 1383 } 1384 1385 if (sqlenv == null) { 1386 sqlenv = new TSQLEnv(option.getVendor()) { 1387 1388 @Override 1389 public void initSQLEnv() { 1390 // TODO Auto-generated method stub 1391 1392 } 1393 }; 1394 } 1395 ModelBindingManager.setGlobalSQLEnv(sqlenv); 1396 sqlparser.sqltext = databaseMap.get(key).first.toString(); 1397 ModelBindingManager.setGlobalHash(SHA256.getMd5(key)); 1398 analyzeAndOutputResult(sqlparser); 1399 if(sqlenv!=null){ 1400 sqlenv.setDefaultCatalogName(defaultDatabase); 1401 sqlenv.setDefaultSchemaName(defaultSchema); 1402 } 1403 } 1404 1405 appendProcesses(dataflow); 1406 appendOraclePackages(dataflow); 1407 appendProcedures(dataflow); 1408 appendTables(dataflow); 1409 appendViews(dataflow); 1410 appendResultSets(dataflow); 1411 appendRelations(dataflow); 1412 appendErrors(dataflow); 1413 } 1414 1415 dataflow = handleDataflowExecProcedure(dataflow); 1416 1417 if (dataflow != null && option.getAnalyzeMode() != AnalyzeMode.crud) { 1418 if (!isShowJoin()) { 1419 dataflow = mergeTables(dataflow, modelManager.TABLE_COLUMN_ID, option); 1420 } else { 1421 dataflow = removeDuplicateColumns(dataflow); 1422 } 1423 } 1424 1425 if (dataflow != null && option.isNormalizeOutput()) { 1426 dataflow = getNormalizeDataflow(dataflow); 1427 } 1428 1429 if (dataflow != null && option.isIgnoreCoordinate()) { 1430 dataflow = filterDataflowCoordinate(dataflow); 1431 } 1432 1433 if (option.isSimpleOutput() || option.isIgnoreRecordSet()) { 1434 List<String> showTypes = new ArrayList<>(); 1435 if(option.getSimpleShowRelationTypes()!=null) { 1436 showTypes.addAll(option.getSimpleShowRelationTypes()); 1437 } 1438 if(showTypes.isEmpty()) { 1439 showTypes.add("fdd"); 1440 } 1441 if(option.isShowCallRelation()) { 1442 showTypes.add("call"); 1443 } 1444 if(option.isShowERDiagram()) { 1445 showTypes.add("er"); 1446 } 1447 dataflow simpleDataflow = getSimpleDataflow(dataflow, option.isSimpleOutput(), showTypes); 1448 if (simpleDataflow.getResultsets() != null) { 1449 for (table t : simpleDataflow.getResultsets()) { 1450 t.setIsTarget(null); 1451 } 1452 } 1453 return simpleDataflow; 1454 } else { 1455 return dataflow; 1456 } 1457 1458 } catch (Exception e) { 1459 logger.error("analyze sql failed.", e); 1460 ErrorInfo errorInfo = new ErrorInfo(); 1461 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 1462 if (e.getMessage() == null) { 1463 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 1464 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 1465 } else { 1466 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 1467 } 1468 } else { 1469 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 1470 } 1471 errorInfo.fillInfo(this); 1472 errorInfos.add(errorInfo); 1473 } 1474 1475 modelManager.reset(); 1476 return null; 1477 } 1478 1479 private dataflow handleDataflowExecProcedure(dataflow dataflow) { 1480 Set<String> procedures = new HashSet<String>(); 1481 for (procedure procedure : dataflow.getProcedures()) { 1482 procedures.add(DlineageUtil.getIdentifierNormalTableName(procedure.getName())); 1483 } 1484 List<table> removeResultSets = new ArrayList<table>(); 1485 1486 Map<String, table> allMap = new HashMap<String, table>(); 1487 1488 if (dataflow.getResultsets() != null) { 1489 for (table t : dataflow.getResultsets()) { 1490 allMap.put(t.getId().toLowerCase(), t); 1491 } 1492 } 1493 1494 if (dataflow.getTables() != null) { 1495 for (table t : dataflow.getTables()) { 1496 allMap.put(t.getId().toLowerCase(), t); 1497 } 1498 } 1499 1500 if (dataflow.getViews() != null) { 1501 for (table t : dataflow.getViews()) { 1502 allMap.put(t.getId().toLowerCase(), t); 1503 } 1504 } 1505 1506 if (dataflow.getVariables() != null) { 1507 for (table t : dataflow.getVariables()) { 1508 allMap.put(t.getId().toLowerCase(), t); 1509 } 1510 } 1511 1512 1513 for (table resultSet : dataflow.getResultsets()) { 1514 String resultSetName = DlineageUtil.getIdentifierNormalTableName(resultSet.getName()); 1515 if (!(ResultSetType.function.name().equals(resultSet.getType()) 1516 && modelManager.getFunctionTable(resultSetName) != null && procedures.contains(resultSetName))) { 1517 continue; 1518 } 1519 1520 Set<Object> functionTables = modelManager 1521 .getFunctionTable(DlineageUtil.getIdentifierNormalTableName(resultSet.getName())); 1522 List<ResultSet> functionResults = functionTables.stream().filter(t -> t instanceof ResultSet) 1523 .map(t -> (ResultSet) t).collect(Collectors.toList()); 1524 if (!(resultSet.getColumns().size() == 1 1525 && DlineageUtil.getIdentifierNormalTableName(resultSet.getColumns().get(0).getName()).equals(resultSetName)) 1526 || functionResults.isEmpty()) { 1527 continue; 1528 } 1529 1530 column column = resultSet.getColumns().get(0); 1531 String sourceColumnId = column.getId(); 1532 boolean reserveResultSet = false; 1533 List<relationship> appendRelations = new ArrayList<relationship>(); 1534 Set<relationship> removeRelations = new HashSet<relationship>(); 1535 1536 for (relationship relationship : dataflow.getRelationships()) { 1537 targetColumn targetColumn = relationship.getTarget(); 1538 List<sourceColumn> sourceColumns = relationship.getSources(); 1539 List<sourceColumn> newSourceColumns = new ArrayList<sourceColumn>(); 1540 for (sourceColumn sourceColumn : sourceColumns) { 1541 if (!sourceColumn.getId().equals(sourceColumnId)) { 1542 continue; 1543 } 1544 for (ResultSet sourceResultSet : functionResults) { 1545 for (ResultColumn resultColumn : sourceResultSet.getColumns()) { 1546 if (!DlineageUtil.compareColumnIdentifier(resultColumn.getName(), 1547 targetColumn.getColumn())) { 1548 if (targetColumn.getColumn().endsWith("*")) { 1549 table parent = allMap.get(targetColumn.getParent_id()); 1550 if (parent != null && parent.getColumns().size() > 1) { 1551 for (column item : parent.getColumns()) { 1552 if (DlineageUtil.compareColumnIdentifier(resultColumn.getName(), 1553 item.getName())) { 1554 relationship newRelation = appendStarRelation(dataflow, relationship, item, resultColumn); 1555 appendRelations.add(newRelation); 1556 removeRelations.add(relationship); 1557 newSourceColumns.add(newRelation.getSources().get(0)); 1558 if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) { 1559 dataflow.getResultsets().stream().filter( 1560 t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId()))) 1561 .forEach(t -> t.setIsTarget(Boolean.FALSE.toString())); 1562 } 1563 } 1564 } 1565 } 1566 } 1567 continue; 1568 } 1569 1570 sourceColumn sourceColumn1 = new sourceColumn(); 1571 sourceColumn1.setId(String.valueOf(resultColumn.getId())); 1572 sourceColumn1.setColumn(resultColumn.getName()); 1573 sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId())); 1574 sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet())); 1575 if (resultColumn.getStartPosition() != null 1576 && resultColumn.getEndPosition() != null) { 1577 sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition()) 1578 + "," + convertCoordinate(resultColumn.getEndPosition())); 1579 } 1580 newSourceColumns.add(sourceColumn1); 1581 1582 if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) { 1583 dataflow.getResultsets().stream().filter( 1584 t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId()))) 1585 .forEach(t -> t.setIsTarget(Boolean.FALSE.toString())); 1586 } 1587 } 1588 } 1589 1590 if (!newSourceColumns.isEmpty()) { 1591 if (removeRelations.isEmpty()) { 1592 relationship.setSources(newSourceColumns); 1593 } 1594 } 1595 else { 1596 reserveResultSet = true; 1597 } 1598 } 1599 } 1600 1601 dataflow.getRelationships().addAll(appendRelations); 1602 dataflow.getRelationships().removeAll(removeRelations); 1603 1604 if(!reserveResultSet) { 1605 removeResultSets.add(resultSet); 1606 } 1607 } 1608 dataflow.getResultsets().removeAll(removeResultSets); 1609 return dataflow; 1610 } 1611 1612 private relationship appendStarRelation(dataflow dataflow, 1613 relationship relationship, column item, ResultColumn resultColumn) { 1614 relationship relationElement = new relationship(); 1615 relationElement.setType(relationship.getType()); 1616 relationElement.setEffectType(relationship.getEffectType()); 1617 relationElement.setSqlHash(relationship.getSqlHash()); 1618 relationElement.setSqlComment(relationship.getSqlComment()); 1619 relationElement.setProcedureId(relationship.getProcedureId()); 1620 relationElement.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID)); 1621 relationElement.setProcessId(relationship.getProcessId()); 1622 relationElement.setProcessType(relationship.getProcessType()); 1623 1624 targetColumn targetColumn1 = new targetColumn(); 1625 targetColumn1.setId(String.valueOf(item.getId())); 1626 targetColumn1.setColumn(item.getName()); 1627 targetColumn1.setParent_id(relationship.getTarget().getParent_id()); 1628 targetColumn1.setParent_name(relationship.getTarget().getParent_name()); 1629 targetColumn1.setParent_alias(relationship.getTarget().getParent_alias()); 1630 if (relationship.getTarget().getCoordinate() != null) { 1631 targetColumn1.setCoordinate(item.getCoordinate()); 1632 } 1633 relationElement.setTarget(targetColumn1); 1634 1635 sourceColumn sourceColumn1 = new sourceColumn(); 1636 sourceColumn1.setId(String.valueOf(resultColumn.getId())); 1637 sourceColumn1.setColumn(resultColumn.getName()); 1638 sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId())); 1639 sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet())); 1640 if (resultColumn.getStartPosition() != null 1641 && resultColumn.getEndPosition() != null) { 1642 sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition()) 1643 + "," + convertCoordinate(resultColumn.getEndPosition())); 1644 } 1645 relationElement.addSource(sourceColumn1); 1646 return relationElement; 1647 } 1648 1649 private dataflow getNormalizeDataflow(dataflow instance) { 1650 List<table> tables = new ArrayList<>(); 1651 if (instance.getResultsets() != null) { 1652 for (table t : instance.getResultsets()) { 1653 tables.add(t); 1654 } 1655 } 1656 1657 if (instance.getTables() != null) { 1658 for (table t : instance.getTables()) { 1659 tables.add(t); 1660 } 1661 } 1662 1663 if (instance.getViews() != null) { 1664 for (table t : instance.getViews()) { 1665 tables.add(t); 1666 } 1667 } 1668 1669 if (instance.getPaths() != null) { 1670 for (table t : instance.getPaths()) { 1671 tables.add(t); 1672 } 1673 } 1674 1675 if (instance.getStages() != null) { 1676 for (table t : instance.getStages()) { 1677 tables.add(t); 1678 } 1679 } 1680 1681 if (instance.getSequences() != null) { 1682 for (table t : instance.getSequences()) { 1683 tables.add(t); 1684 } 1685 } 1686 1687 if (instance.getDatasources() != null) { 1688 for (table t : instance.getDatasources()) { 1689 tables.add(t); 1690 } 1691 } 1692 1693 if (instance.getDatabases() != null) { 1694 for (table t : instance.getDatabases()) { 1695 tables.add(t); 1696 } 1697 } 1698 1699 if (instance.getSchemas() != null) { 1700 for (table t : instance.getSchemas()) { 1701 tables.add(t); 1702 } 1703 } 1704 1705 if (instance.getStreams() != null) { 1706 for (table t : instance.getStreams()) { 1707 tables.add(t); 1708 } 1709 } 1710 1711 if (instance.getVariables() != null) { 1712 for (table t : instance.getVariables()) { 1713 tables.add(t); 1714 } 1715 } 1716 1717 Map<String, String> idNameMap = new HashMap(); 1718 1719 for(table table: tables){ 1720 if(table.getDatabase()!=null) { 1721 table.setDatabase(DlineageUtil.getIdentifierNormalName(table.getDatabase(), ESQLDataObjectType.dotCatalog)); 1722 } 1723 if(table.getSchema()!=null) { 1724 table.setSchema(DlineageUtil.getIdentifierNormalName(table.getSchema(), ESQLDataObjectType.dotSchema)); 1725 } 1726 if(table.getName()!=null) { 1727 table.setName(DlineageUtil.getIdentifierNormalName(table.getName(), ESQLDataObjectType.dotTable)); 1728 idNameMap.put(table.getId(), table.getName()); 1729 } 1730 if(table.getColumns()!=null){ 1731 for(column column: table.getColumns()){ 1732 column.setName(DlineageUtil.getIdentifierNormalName(column.getName(), ESQLDataObjectType.dotColumn)); 1733 idNameMap.put(column.getId(), column.getName()); 1734 } 1735 } 1736 } 1737 if(instance.getPackages()!=null){ 1738 for(oraclePackage oraclePackage: instance.getPackages()){ 1739 if(oraclePackage.getDatabase()!=null) { 1740 oraclePackage.setDatabase(DlineageUtil.getIdentifierNormalName(oraclePackage.getDatabase(), ESQLDataObjectType.dotCatalog)); 1741 } 1742 if(oraclePackage.getSchema()!=null) { 1743 oraclePackage.setSchema(DlineageUtil.getIdentifierNormalName(oraclePackage.getSchema(), ESQLDataObjectType.dotSchema)); 1744 } 1745 if(oraclePackage.getName()!=null) { 1746 oraclePackage.setName(DlineageUtil.getIdentifierNormalName(oraclePackage.getName(), ESQLDataObjectType.dotTable)); 1747 idNameMap.put(oraclePackage.getId(), oraclePackage.getName()); 1748 } 1749 if(oraclePackage.getArguments()!=null){ 1750 for(argument argument: oraclePackage.getArguments()){ 1751 argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn)); 1752 idNameMap.put(argument.getId(), argument.getName()); 1753 } 1754 } 1755 if(oraclePackage.getProcedures()!=null){ 1756 for(procedure procedure: oraclePackage.getProcedures()){ 1757 if(procedure.getDatabase()!=null) { 1758 procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog)); 1759 } 1760 if(procedure.getSchema()!=null) { 1761 procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema)); 1762 } 1763 if(procedure.getName()!=null) { 1764 procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable)); 1765 idNameMap.put(procedure.getId(), procedure.getName()); 1766 } 1767 for(argument argument: procedure.getArguments()){ 1768 argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn)); 1769 idNameMap.put(argument.getId(), argument.getName()); 1770 } 1771 } 1772 } 1773 } 1774 } 1775 if(instance.getProcedures()!=null){ 1776 for(procedure procedure: instance.getProcedures()){ 1777 if(procedure.getDatabase()!=null) { 1778 procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog)); 1779 } 1780 if(procedure.getSchema()!=null) { 1781 procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema)); 1782 } 1783 if(procedure.getName()!=null) { 1784 procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable)); 1785 idNameMap.put(procedure.getId(), procedure.getName()); 1786 } 1787 for(argument argument: procedure.getArguments()){ 1788 argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn)); 1789 idNameMap.put(argument.getId(), argument.getName()); 1790 } 1791 } 1792 } 1793 if (instance.getProcesses() != null) { 1794 for (process process : instance.getProcesses()) { 1795 if(process.getDatabase()!=null) { 1796 process.setDatabase(DlineageUtil.getIdentifierNormalName(process.getDatabase(), ESQLDataObjectType.dotCatalog)); 1797 } 1798 if(process.getSchema()!=null) { 1799 process.setSchema(DlineageUtil.getIdentifierNormalName(process.getSchema(), ESQLDataObjectType.dotSchema)); 1800 } 1801 if (process.getProcedureId() != null) { 1802 process.setProcedureName(DlineageUtil.getIdentifierNormalName(process.getProcedureName(), ESQLDataObjectType.dotTable)); 1803 idNameMap.put(process.getId(), process.getName()); 1804 } 1805 } 1806 } 1807 1808 if(instance.getRelationships()!=null){ 1809 for(relationship relation: instance.getRelationships()){ 1810 targetColumn targetColumn = relation.getTarget(); 1811 if(targetColumn != null) { 1812 targetColumn.setColumn(idNameMap.get(targetColumn.getId())); 1813 targetColumn.setTarget_name(idNameMap.get(targetColumn.getTarget_id())); 1814 targetColumn.setParent_name(idNameMap.get(targetColumn.getParent_id())); 1815 } 1816 List<sourceColumn> sourceColumns = relation.getSources(); 1817 if(sourceColumns!=null){ 1818 for(sourceColumn sourceColumn: sourceColumns){ 1819 sourceColumn.setColumn(idNameMap.get(sourceColumn.getId())); 1820 sourceColumn.setSource_name(idNameMap.get(sourceColumn.getSource_id())); 1821 sourceColumn.setParent_name(idNameMap.get(sourceColumn.getParent_id())); 1822 } 1823 } 1824 targetColumn = relation.getCaller(); 1825 if(targetColumn != null) { 1826 targetColumn.setName(idNameMap.get(targetColumn.getId())); 1827 } 1828 sourceColumns = relation.getCallees(); 1829 if(sourceColumns!=null){ 1830 for(sourceColumn sourceColumn: sourceColumns){ 1831 sourceColumn.setName(idNameMap.get(sourceColumn.getId())); 1832 } 1833 } 1834 } 1835 } 1836 1837 1838 return instance; 1839 } 1840 1841 private dataflow filterDataflowCoordinate(dataflow instance) { 1842 List<table> tables = new ArrayList<>(); 1843 if (instance.getResultsets() != null) { 1844 for (table t : instance.getResultsets()) { 1845 tables.add(t); 1846 } 1847 } 1848 1849 if (instance.getTables() != null) { 1850 for (table t : instance.getTables()) { 1851 tables.add(t); 1852 } 1853 } 1854 1855 if (instance.getViews() != null) { 1856 for (table t : instance.getViews()) { 1857 tables.add(t); 1858 } 1859 } 1860 1861 if (instance.getPaths() != null) { 1862 for (table t : instance.getPaths()) { 1863 tables.add(t); 1864 } 1865 } 1866 1867 if (instance.getStages() != null) { 1868 for (table t : instance.getStages()) { 1869 tables.add(t); 1870 } 1871 } 1872 1873 if (instance.getSequences() != null) { 1874 for (table t : instance.getSequences()) { 1875 tables.add(t); 1876 } 1877 } 1878 1879 if (instance.getDatasources() != null) { 1880 for (table t : instance.getDatasources()) { 1881 tables.add(t); 1882 } 1883 } 1884 1885 if (instance.getDatabases() != null) { 1886 for (table t : instance.getDatabases()) { 1887 tables.add(t); 1888 } 1889 } 1890 1891 if (instance.getSchemas() != null) { 1892 for (table t : instance.getSchemas()) { 1893 tables.add(t); 1894 } 1895 } 1896 1897 if (instance.getStreams() != null) { 1898 for (table t : instance.getStreams()) { 1899 tables.add(t); 1900 } 1901 } 1902 1903 if (instance.getVariables() != null) { 1904 for (table t : instance.getVariables()) { 1905 tables.add(t); 1906 } 1907 } 1908 1909 for(table table: tables){ 1910 table.clearCoordinate(); 1911 if(table.getColumns()!=null){ 1912 for(column column: table.getColumns()){ 1913 column.clearCoordinate(); 1914 } 1915 } 1916 } 1917 if(instance.getPackages()!=null){ 1918 for(oraclePackage oraclePackage: instance.getPackages()){ 1919 oraclePackage.setCoordinate(null); 1920 if(oraclePackage.getProcedures()!=null){ 1921 for(procedure procedure: oraclePackage.getProcedures()){ 1922 procedure.setCoordinate(null); 1923 for(argument argument: procedure.getArguments()){ 1924 argument.setCoordinate(null); 1925 } 1926 } 1927 } 1928 } 1929 } 1930 if(instance.getProcedures()!=null){ 1931 for(procedure procedure: instance.getProcedures()){ 1932 procedure.setCoordinate(null); 1933 for(argument argument: procedure.getArguments()){ 1934 argument.setCoordinate(null); 1935 } 1936 } 1937 } 1938 if (instance.getProcesses() != null) { 1939 for (process process : instance.getProcesses()) { 1940 process.setCoordinate(null); 1941 } 1942 } 1943 1944 if(instance.getRelationships()!=null){ 1945 for(relationship relation: instance.getRelationships()){ 1946 targetColumn targetColumn = relation.getTarget(); 1947 if(targetColumn != null) { 1948 targetColumn.setCoordinate(null); 1949 } 1950 List<sourceColumn> sourceColumns = relation.getSources(); 1951 if(sourceColumns!=null){ 1952 for(sourceColumn sourceColumn: sourceColumns){ 1953 sourceColumn.setCoordinate(null); 1954 } 1955 } 1956 targetColumn = relation.getCaller(); 1957 if(targetColumn != null) { 1958 targetColumn.setCoordinate(null); 1959 } 1960 sourceColumns = relation.getCallees(); 1961 if(sourceColumns!=null){ 1962 for(sourceColumn sourceColumn: sourceColumns){ 1963 sourceColumn.setCoordinate(null); 1964 } 1965 } 1966 } 1967 } 1968 1969 return instance; 1970 } 1971 1972 private void appendSqlInfo(Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap, int index, 1973 SqlInfo sqlInfo, Map queryObject) { 1974 EDbVendor vendor = option.getVendor(); 1975 if (!SQLUtil.isEmpty(sqlInfo.getDbVendor())) { 1976 vendor = EDbVendor.valueOf(sqlInfo.getDbVendor()); 1977 } 1978 1979 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 1980 boolean supportSchema = TSQLEnv.supportSchema(vendor); 1981 1982 String groupName = (String) queryObject.get("groupName"); 1983 if (DlineageUtil.isProcedureExcluded(groupName)) { 1984 return; 1985 } 1986 1987 String content = (String) queryObject.get("sourceCode"); 1988 if (SQLUtil.isEmpty(content)) { 1989 return; 1990 } 1991 StringBuilder builder = new StringBuilder(); 1992 if (supportCatalog) { 1993 String database = (String) queryObject.get("database"); 1994 if (database.indexOf(".") != -1) { 1995 String delimitedChar = TSQLEnv.delimitedChar(vendor); 1996 database = delimitedChar + SQLUtil.trimColumnStringQuote(database) + delimitedChar; 1997 } 1998 builder.append(database); 1999 } 2000 if (supportSchema) { 2001 String schema = (String) queryObject.get("schema"); 2002 if (schema.indexOf(".") != -1) { 2003 String delimitedChar = TSQLEnv.delimitedChar(vendor); 2004 schema = delimitedChar + SQLUtil.trimColumnStringQuote(schema) + delimitedChar; 2005 } 2006 if (builder.length() > 0) { 2007 builder.append("."); 2008 } 2009 builder.append(schema); 2010 } 2011 String group = builder.toString(); 2012 String sqlHash = SHA256.getMd5(content); 2013 String hash = SHA256.getMd5(sqlHash); 2014 if (!databaseMap.containsKey(sqlHash)) { 2015 databaseMap.put(sqlHash, 2016 new Pair3<StringBuilder, AtomicInteger, String>(new StringBuilder(), new AtomicInteger(), group)); 2017 } 2018 TGSqlParser parser = new TGSqlParser(option.getVendor()); 2019 String delimiterChar = String.valueOf(parser.getDelimiterChar()); 2020 StringBuilder buffer = new StringBuilder(content); 2021 if (content.trim().endsWith(delimiterChar) || content.trim().endsWith(";")) { 2022 buffer.append("\n"); 2023 } else if(vendor == EDbVendor.dbvredshift 2024 || vendor == EDbVendor.dbvgaussdb 2025 || vendor == EDbVendor.dbvedb 2026 || vendor == EDbVendor.dbvpostgresql 2027 || vendor == EDbVendor.dbvmysql 2028 || vendor == EDbVendor.dbvteradata){ 2029 buffer.append("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n"); 2030 } else{ 2031 SQLUtil.endTrim(buffer); 2032 buffer.append(";").append("\n"); 2033 } 2034 2035 int lineStart = databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1; 2036 if (databaseMap.get(sqlHash).first.toString().length() == 0) { 2037 lineStart = 0; 2038 } 2039 databaseMap.get(sqlHash).first.append(buffer.toString()); 2040 SqlInfo sqlInfoItem = new SqlInfo(); 2041 sqlInfoItem.setServer(sqlInfo.getServer()); 2042 sqlInfoItem.setDbVendor(sqlInfo.getDbVendor()); 2043 sqlInfoItem.setFileName(sqlInfo.getFileName()); 2044 sqlInfoItem.setFilePath(sqlInfo.getFilePath()); 2045 sqlInfoItem.setSql(buffer.toString()); 2046 sqlInfoItem.setOriginIndex(index); 2047 sqlInfoItem.setOriginLineStart(0); 2048 sqlInfoItem.setOriginLineEnd(buffer.toString().split("\n", -1).length - 1); 2049 sqlInfoItem.setIndex(databaseMap.get(sqlHash).second.getAndIncrement()); 2050 sqlInfoItem.setLineStart(lineStart); 2051 sqlInfoItem.setLineEnd(databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1); 2052 sqlInfoItem.setGroup(group); 2053 sqlInfoItem.setHash(hash); 2054 2055 if (!sqlInfoMap.containsKey(hash)) { 2056 sqlInfoMap.put(hash, new ArrayList<SqlInfo>()); 2057 } 2058 sqlInfoMap.get(hash).add(sqlInfoItem); 2059 } 2060 2061 static String getTextOutput(dataflow dataflow) { 2062 StringBuffer buffer = new StringBuffer(); 2063 List<relationship> relations = dataflow.getRelationships(); 2064 if (relations != null) { 2065 for (int i = 0; i < relations.size(); i++) { 2066 relationship relation = relations.get(i); 2067 targetColumn target = relation.getTarget(); 2068 List<sourceColumn> sources = relation.getSources(); 2069 if (target != null && sources != null && sources.size() > 0) { 2070 buffer.append(target.getColumn()).append(" depends on: "); 2071 Set<String> columnSet = new LinkedHashSet<String>(); 2072 for (int j = 0; j < sources.size(); j++) { 2073 sourceColumn sourceColumn = sources.get(j); 2074 String columnName = sourceColumn.getColumn(); 2075 if (sourceColumn.getParent_name() != null && sourceColumn.getParent_name().length() > 0) { 2076 columnName = sourceColumn.getParent_name() + "." + columnName; 2077 } 2078 columnSet.add(columnName); 2079 } 2080 String[] columns = columnSet.toArray(new String[0]); 2081 for (int j = 0; j < columns.length; j++) { 2082 buffer.append(columns[j]); 2083 if (j == columns.length - 1) { 2084 buffer.append("\n"); 2085 } else 2086 buffer.append(", "); 2087 } 2088 } 2089 } 2090 } 2091 return buffer.toString(); 2092 } 2093 2094 private String mergeRelationType(List<Pair<sourceColumn, List<String>>> typePaths) { 2095 RelationshipType relationType = RelationshipType.join; 2096 for (int i = 0; i < typePaths.size(); i++) { 2097 List<String> path = typePaths.get(i).second; 2098 RelationshipType type = RelationshipType.valueOf(getRelationType(path)); 2099 if (type.ordinal() < relationType.ordinal()) { 2100 relationType = type; 2101 } 2102 } 2103 return relationType.name(); 2104 } 2105 2106 private String getRelationType(List<String> typePaths) { 2107 if (typePaths.contains("join")) 2108 return "join"; 2109 if (typePaths.contains("fdr")) 2110 return "fdr"; 2111 if (typePaths.contains("frd")) 2112 return "frd"; 2113 if (typePaths.contains("fddi")) 2114 return "fddi"; 2115 return "fdd"; 2116 } 2117 2118 public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput) throws Exception { 2119 return getSimpleDataflow(instance, simpleOutput, Arrays.asList("fdd")); 2120 } 2121 2122 public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput, List<String> types) throws Exception { 2123 ModelBindingManager.setGlobalVendor(option.getVendor()); 2124 allMap.clear(); 2125 targetTables.clear(); 2126 resultSetMap.clear(); 2127 tableMap.clear(); 2128 viewMap.clear(); 2129 cursorMap.clear(); 2130 variableMap.clear(); 2131 fileMap.clear(); 2132 stageMap.clear(); 2133 sequenceMap.clear(); 2134 dataSourceMap.clear(); 2135 databaseMap.clear(); 2136 schemaMap.clear(); 2137 streamMap.clear(); 2138 dataflow simple = new dataflow(); 2139 List<relationship> simpleRelations = new ArrayList<relationship>(); 2140 List<relationship> relations = instance.getRelationships(); 2141 if (instance.getResultsets() != null) { 2142 for (table t : instance.getResultsets()) { 2143 resultSetMap.put(t.getId().toLowerCase(), t); 2144 allMap.put(t.getId().toLowerCase(), t); 2145 } 2146 } 2147 2148 if (instance.getTables() != null) { 2149 for (table t : instance.getTables()) { 2150 tableMap.put(t.getId().toLowerCase(), t); 2151 allMap.put(t.getId().toLowerCase(), t); 2152 } 2153 } 2154 2155 if (instance.getViews() != null) { 2156 for (table t : instance.getViews()) { 2157 viewMap.put(t.getId().toLowerCase(), t); 2158 allMap.put(t.getId().toLowerCase(), t); 2159 } 2160 } 2161 2162 if (instance.getPaths() != null) { 2163 for (table t : instance.getPaths()) { 2164 fileMap.put(t.getId().toLowerCase(), t); 2165 allMap.put(t.getId().toLowerCase(), t); 2166 } 2167 } 2168 2169 if (instance.getStages() != null) { 2170 for (table t : instance.getStages()) { 2171 stageMap.put(t.getId().toLowerCase(), t); 2172 allMap.put(t.getId().toLowerCase(), t); 2173 } 2174 } 2175 2176 if (instance.getSequences() != null) { 2177 for (table t : instance.getSequences()) { 2178 sequenceMap.put(t.getId().toLowerCase(), t); 2179 allMap.put(t.getId().toLowerCase(), t); 2180 } 2181 } 2182 2183 if (instance.getDatasources() != null) { 2184 for (table t : instance.getDatasources()) { 2185 dataSourceMap.put(t.getId().toLowerCase(), t); 2186 allMap.put(t.getId().toLowerCase(), t); 2187 } 2188 } 2189 2190 if (instance.getDatabases() != null) { 2191 for (table t : instance.getDatabases()) { 2192 databaseMap.put(t.getId().toLowerCase(), t); 2193 allMap.put(t.getId().toLowerCase(), t); 2194 } 2195 } 2196 2197 if (instance.getSchemas() != null) { 2198 for (table t : instance.getSchemas()) { 2199 schemaMap.put(t.getId().toLowerCase(), t); 2200 allMap.put(t.getId().toLowerCase(), t); 2201 } 2202 } 2203 2204 if (instance.getStreams() != null) { 2205 for (table t : instance.getStreams()) { 2206 streamMap.put(t.getId().toLowerCase(), t); 2207 allMap.put(t.getId().toLowerCase(), t); 2208 } 2209 } 2210 2211 if (instance.getVariables() != null) { 2212 for (table t : instance.getVariables()) { 2213 if(SubType.cursor.name().equals(t.getSubType())){ 2214 cursorMap.put(t.getId().toLowerCase(), t); 2215 } 2216 else { 2217 variableMap.put(t.getId().toLowerCase(), t); 2218 } 2219 allMap.put(t.getId().toLowerCase(), t); 2220 } 2221 } 2222 2223 if (relations != null) { 2224 2225 List<relationship> filterRelations = new ArrayList<>(); 2226 for (relationship relationElem : relations) { 2227 if (!types.contains(relationElem.getType())) 2228 continue; 2229 else { 2230 filterRelations.add(relationElem); 2231 } 2232 } 2233 2234 relations = filterRelations; 2235 2236 Map<String, Set<relationship>> targetIdRelationMap = new HashMap<String, Set<relationship>>(); 2237 for (relationship relation : relations) { 2238 if (relation.getTarget() != null) { 2239 String key = relation.getTarget().getParent_id() + "." + relation.getTarget().getId(); 2240 if (!targetIdRelationMap.containsKey(key)) { 2241 targetIdRelationMap.put(key, new TreeSet<relationship>(new Comparator<relationship>() { 2242 @Override 2243 public int compare(relationship o1, relationship o2) { 2244 return o1.getId().compareTo(o2.getId()); 2245 } 2246 })); 2247 } 2248 targetIdRelationMap.get(key).add(relation); 2249 } 2250 } 2251 2252 Iterator<String> keys = targetIdRelationMap.keySet().iterator(); 2253 while (keys.hasNext()) { 2254 String key = keys.next(); 2255 if (targetIdRelationMap.get(key).size() > 500) { 2256 keys.remove(); 2257 } 2258 } 2259 2260 for (relationship relationElem : relations) { 2261 if (RelationshipType.call.name().equals(relationElem.getType())) { 2262 continue; 2263 } 2264 if (RelationshipType.er.name().equals(relationElem.getType())) { 2265 continue; 2266 } 2267 targetColumn target = relationElem.getTarget(); 2268 String targetParent = target.getParent_id(); 2269 if (isTarget(instance, targetParent, simpleOutput)) { 2270 List<Pair<sourceColumn, List<String>>> relationSources = new ArrayList<Pair<sourceColumn, List<String>>>(); 2271 findSourceRelations(target, instance, targetIdRelationMap, relationElem, relationSources, 2272 new String[] { relationElem.getType() }, simpleOutput); 2273 if (relationSources.size() > 0) { 2274 Map<sourceColumn, List<Pair<sourceColumn, List<String>>>> columnMap = new LinkedHashMap<sourceColumn, List<Pair<sourceColumn, List<String>>>>(); 2275 for (Pair<sourceColumn, List<String>> t : relationSources) { 2276 sourceColumn key = ((Pair<sourceColumn, List<String>>) t).first; 2277 if (!columnMap.containsKey(key)) { 2278 columnMap.put(key, new ArrayList<Pair<sourceColumn, List<String>>>()); 2279 } 2280 columnMap.get(key).add(t); 2281 } 2282 Iterator<sourceColumn> iter = columnMap.keySet().iterator(); 2283 Map<String, List<sourceColumn>> relationSourceMap = new HashMap<String, List<sourceColumn>>(); 2284 while (iter.hasNext()) { 2285 sourceColumn column = iter.next(); 2286 String relationType = mergeRelationType(columnMap.get(column)); 2287 if (!relationSourceMap.containsKey(relationType)) { 2288 relationSourceMap.put(relationType, new ArrayList<sourceColumn>()); 2289 } 2290 relationSourceMap.get(relationType).add(column); 2291 } 2292 2293 Iterator<String> sourceIter = relationSourceMap.keySet().iterator(); 2294 while (sourceIter.hasNext()) { 2295 String relationType = sourceIter.next(); 2296 relationship simpleRelation = (relationship) relationElem.clone(); 2297 simpleRelation.setSources(relationSourceMap.get(relationType)); 2298 simpleRelation.setType(relationType); 2299 simpleRelation.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID)); 2300 simpleRelations.add(simpleRelation); 2301 } 2302 } 2303 } 2304 } 2305 } 2306 2307 simple.setProcedures(instance.getProcedures()); 2308 simple.setPackages(instance.getPackages()); 2309 simple.setProcesses(instance.getProcesses()); 2310 simple.setErrors(instance.getErrors()); 2311 List<table> tables = new ArrayList<table>(); 2312 for (table t : instance.getTables()) { 2313 if (!SQLUtil.isTempTable(t)) { 2314 tables.add(t); 2315 } 2316 else { 2317 if (option.isIgnoreTemporaryTable()) { 2318 continue; 2319 } 2320 else { 2321 tables.add(t); 2322 } 2323 } 2324 } 2325 simple.setStages(instance.getStages()); 2326 simple.setSequences(instance.getSequences()); 2327 simple.setDatasources(instance.getDatasources()); 2328 simple.setStreams(instance.getStreams()); 2329 simple.setPaths(instance.getPaths()); 2330 simple.setTables(tables); 2331 simple.setViews(instance.getViews()); 2332 if(option.isSimpleShowVariable()) { 2333 simple.setVariables(instance.getVariables()); 2334 } 2335 else if(option.isSimpleShowCursor()) { 2336 simple.setVariables(instance.getVariables().stream().filter(t->SubType.cursor.name().equals(t.getSubType())).collect(Collectors.toList())); 2337 } 2338 if (instance.getResultsets() != null) { 2339 List<table> resultSets = new ArrayList<table>(); 2340 for (int i = 0; i < instance.getResultsets().size(); i++) { 2341 table resultSet = instance.getResultsets().get(i); 2342 if (isTargetResultSet(instance, resultSet.getId(), simpleOutput)) { 2343 // special handle function #524 #296 2344 resultSets.add(resultSet); 2345 } 2346 } 2347 simple.setResultsets(resultSets); 2348 } 2349 2350 List<table> functions = new ArrayList<table>(); 2351 if (option.isShowCallRelation()) { 2352 for (int i = 0; i < relations.size(); i++) { 2353 relationship relationElem = relations.get(i); 2354 if (!RelationshipType.call.name().equals(relationElem.getType())) { 2355 continue; 2356 } 2357 simpleRelations.add(relationElem); 2358 for (sourceColumn callee : relationElem.getCallees()) { 2359 String calleeId = callee.getId(); 2360 if (resultSetMap.containsKey(calleeId)) { 2361 table function = resultSetMap.get(calleeId); 2362 function.setIsTarget("true"); 2363 functions.add(function); 2364 } 2365 } 2366 } 2367 } 2368 2369 if (option.isShowERDiagram()) { 2370 for (int i = 0; i < relations.size(); i++) { 2371 relationship relationElem = relations.get(i); 2372 if (!RelationshipType.er.name().equals(relationElem.getType())) { 2373 continue; 2374 } 2375 simpleRelations.add(relationElem); 2376 for (sourceColumn callee : relationElem.getCallees()) { 2377 String calleeId = callee.getId(); 2378 if (resultSetMap.containsKey(calleeId)) { 2379 table function = resultSetMap.get(calleeId); 2380 function.setIsTarget("true"); 2381 functions.add(function); 2382 } 2383 } 2384 } 2385 } 2386 2387 if (!functions.isEmpty()) { 2388 if (simple.getResultsets() == null) { 2389 simple.setResultsets(functions); 2390 } else { 2391 simple.getResultsets().addAll(functions); 2392 } 2393 } 2394 2395 simple.setRelationships(simpleRelations); 2396 simple.setOrientation(instance.getOrientation()); 2397 targetTables.clear(); 2398 resultSetMap.clear(); 2399 tableMap.clear(); 2400 viewMap.clear(); 2401 cursorMap.clear(); 2402 variableMap.clear(); 2403 fileMap.clear(); 2404 stageMap.clear(); 2405 dataSourceMap.clear(); 2406 databaseMap.clear(); 2407 schemaMap.clear(); 2408 streamMap.clear(); 2409 return simple; 2410 } 2411 2412 private void findSourceRelations(targetColumn target, dataflow instance, Map<String, Set<relationship>> sourceIdRelationMap, 2413 relationship targetRelation, List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, boolean simpleOutput) { 2414 findStarSourceRelations(target, instance, null, sourceIdRelationMap, targetRelation, relationSources, pathTypes, 2415 new HashSet<String>(), new LinkedHashSet<transform>(), new LinkedHashSet<candidateTable>(), 0, simpleOutput); 2416 } 2417 2418 private void findStarSourceRelations(targetColumn target, dataflow instance, targetColumn starRelationTarget, 2419 Map<String, Set<relationship>> sourceIdRelationMap, relationship targetRelation, 2420 List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, Set<String> paths, 2421 Set<transform> transforms, Set<candidateTable> candidateTables, int level, boolean simpleOutput) { 2422 if (targetRelation != null && targetRelation.getSources() != null) { 2423 2424 //获取source为*的Column Parent 2425 String starParentId = null; 2426 for (int i = 0; i < targetRelation.getSources().size(); i++) { 2427 sourceColumn source = targetRelation.getSources().get(i); 2428 if (starRelationTarget != null && "*".equals(source.getColumn())) { 2429 starParentId = source.getParent_id(); 2430 } 2431 } 2432 2433 for (int i = 0; i < targetRelation.getSources().size(); i++) { 2434 sourceColumn source = targetRelation.getSources().get(i); 2435 if (starRelationTarget != null && !"*".equals(source.getColumn()) 2436 && !DlineageUtil.getIdentifierNormalColumnName(starRelationTarget.getColumn()) 2437 .equals(DlineageUtil.getIdentifierNormalColumnName(source.getColumn()))) { 2438 table parent = allMap.get(source.getParent_id()); 2439 if (parent != null && isFunction(parent)) { 2440 // function返回值未知,不对星号做处理 2441 } 2442 else if (parent == null) { 2443 continue; 2444 } else if(starParentId!=null && starParentId.equals(parent.getId())){ 2445 //如果source和 * column的parent相同,则跳过 2446 continue; 2447 } 2448 } 2449 2450 String sourceColumnId = source.getId(); 2451 String sourceParentId = source.getParent_id(); 2452 if (sourceParentId == null || sourceColumnId == null) { 2453 continue; 2454 } 2455 if (isTarget(instance, sourceParentId, simpleOutput)) { 2456 List<transform> transforms2 = new ArrayList<transform>(transforms.size()); 2457 transforms2.addAll(transforms); 2458 Collections.reverse(transforms2); 2459 2460 List<candidateTable> candidateTables2 = new ArrayList<candidateTable>(candidateTables.size()); 2461 candidateTables2.addAll(candidateTables); 2462 2463 sourceColumn sourceColumnCopy = DlineageUtil.copySourceColumn(source); 2464 for (transform t : transforms2) { 2465 sourceColumnCopy.addTransform(t); 2466 } 2467 2468 for (candidateTable t : candidateTables2) { 2469 sourceColumnCopy.addCandidateParent(t); 2470 } 2471 2472 if(Boolean.TRUE.equals(target.isStruct()) && Boolean.TRUE.equals(source.isStruct())) { 2473 List<String> targetColumns = SQLUtil.parseNames(target.getColumn()); 2474 List<String> sourceColumns = SQLUtil.parseNames(source.getColumn()); 2475 if(!DlineageUtil.getIdentifierNormalColumnName(targetColumns.get(targetColumns.size()-1)) 2476 .equals(DlineageUtil.getIdentifierNormalColumnName(sourceColumns.get(sourceColumns.size()-1)))) { 2477 continue; 2478 } 2479 } 2480 relationSources.add(new Pair<sourceColumn, List<String>>(sourceColumnCopy, Arrays.asList(pathTypes))); 2481 } else { 2482 Set<relationship> sourceRelations = sourceIdRelationMap 2483 .get(source.getParent_id() + "." + source.getId()); 2484 if (sourceRelations != null) { 2485 if (paths.contains(source.getParent_id() + "." + source.getId())) { 2486 continue; 2487 } else { 2488 paths.add(source.getParent_id() + "." + source.getId()); 2489 if (source.getTransforms() != null) { 2490 transforms.addAll(source.getTransforms()); 2491 } 2492 if (source.getCandidateParents() != null) { 2493 candidateTables.addAll(source.getCandidateParents()); 2494 } 2495 } 2496 for (relationship relation : sourceRelations) { 2497 LinkedHashSet<transform> transforms2 = new LinkedHashSet<transform>(transforms.size()); 2498 transforms2.addAll(transforms); 2499 LinkedHashSet<candidateTable> candidateTables2 = new LinkedHashSet<candidateTable>(candidateTables.size()); 2500 candidateTables2.addAll(candidateTables); 2501 String[] types = new String[pathTypes.length + 1]; 2502 types[0] = relation.getType(); 2503 System.arraycopy(pathTypes, 0, types, 1, pathTypes.length); 2504 if (!"*".equals(source.getColumn())) { 2505 findStarSourceRelations(target, instance, null, sourceIdRelationMap, relation, relationSources, 2506 types, paths, transforms2, candidateTables2, level + 1, simpleOutput); 2507 } else { 2508 findStarSourceRelations(target, instance, 2509 starRelationTarget == null ? targetRelation.getTarget() : starRelationTarget, 2510 sourceIdRelationMap, relation, relationSources, types, paths, transforms, candidateTables2, 2511 level + 1, simpleOutput); 2512 } 2513 } 2514 } 2515 } 2516 } 2517 } 2518 } 2519 2520 private Map<String, Boolean> targetTables = new HashMap<String, Boolean>(); 2521 private Map<String, table> resultSetMap = new HashMap<String, table>(); 2522 private Map<String, table> tableMap = new HashMap<String, table>(); 2523 private Map<String, table> viewMap = new HashMap<String, table>(); 2524 private Map<String, table> cursorMap = new HashMap<String, table>(); 2525 private Map<String, table> variableMap = new HashMap<String, table>(); 2526 private Map<String, table> fileMap = new HashMap<String, table>(); 2527 private Map<String, table> stageMap = new HashMap<String, table>(); 2528 private Map<String, table> sequenceMap = new HashMap<String, table>(); 2529 private Map<String, table> dataSourceMap = new HashMap<String, table>(); 2530 private Map<String, table> databaseMap = new HashMap<String, table>(); 2531 private Map<String, table> schemaMap = new HashMap<String, table>(); 2532 private Map<String, table> streamMap = new HashMap<String, table>(); 2533 private Map<String, table> allMap = new HashMap<String, table>(); 2534 2535 private boolean isTarget(dataflow instance, String targetParentId, boolean simpleOutput) { 2536 if (targetTables.containsKey(targetParentId)) 2537 return targetTables.get(targetParentId); 2538 if (isTable(instance, targetParentId)) { 2539 targetTables.put(targetParentId, true); 2540 return true; 2541 } else if (isView(instance, targetParentId)) { 2542 targetTables.put(targetParentId, true); 2543 return true; 2544 } else if (isFile(instance, targetParentId)) { 2545 targetTables.put(targetParentId, true); 2546 return true; 2547 } else if (isDatabase(instance, targetParentId)) { 2548 targetTables.put(targetParentId, true); 2549 return true; 2550 } else if (isSchema(instance, targetParentId)) { 2551 targetTables.put(targetParentId, true); 2552 return true; 2553 } else if (isStage(instance, targetParentId)) { 2554 targetTables.put(targetParentId, true); 2555 return true; 2556 } else if (isSequence(instance, targetParentId)) { 2557 targetTables.put(targetParentId, true); 2558 return true; 2559 } else if (isDataSource(instance, targetParentId)) { 2560 targetTables.put(targetParentId, true); 2561 return true; 2562 } else if (isStream(instance, targetParentId)) { 2563 targetTables.put(targetParentId, true); 2564 return true; 2565 } else if (isCursor(instance, targetParentId) && option.isSimpleShowCursor()) { 2566 targetTables.put(targetParentId, true); 2567 return true; 2568 } else if ((isVariable(instance, targetParentId) || isCursor(instance, targetParentId)) && option.isSimpleShowVariable()) { 2569 targetTables.put(targetParentId, true); 2570 return true; 2571 } else if (isTargetResultSet(instance, targetParentId, simpleOutput)) { 2572 targetTables.put(targetParentId, true); 2573 return true; 2574 } 2575 targetTables.put(targetParentId, false); 2576 return false; 2577 } 2578 2579 private boolean isTargetResultSet(dataflow instance, String targetParent, boolean simpleOutput) { 2580 if (resultSetMap.containsKey(targetParent.toLowerCase())) { 2581 table result = resultSetMap.get(targetParent.toLowerCase()); 2582 boolean isTarget = result.isTarget(); 2583 Option option = ModelBindingManager.getGlobalOption(); 2584 if (option != null && option.isSqlflowIgnoreFunction() && isFunction(result)) { 2585 return false; 2586 } 2587 if (isTarget && simpleOutput) { 2588 if (option != null && option.isSimpleShowFunction() && isFunction(result)) { 2589 return true; 2590 2591 } else if (option != null && option.isSimpleShowTopSelectResultSet()) { 2592 return true; 2593 } 2594 if (ResultSetType.of(result.getType()) != null && option.containsResultSetType(ResultSetType.of(result.getType()))) { 2595 return true; 2596 } 2597 } else 2598 return isTarget; 2599 } 2600 return false; 2601 } 2602 2603 private boolean isFunction(table resultSet) { 2604 if("function".equals(resultSet.getType())){ 2605 return true; 2606 } 2607 else if("resultset".equals(resultSet.getType()) && "function".equals(resultSet.getSubType())){ 2608 return true; 2609 } 2610 return false; 2611 } 2612 2613 private boolean isView(dataflow instance, String targetParent) { 2614 if (viewMap.containsKey(targetParent.toLowerCase())) { 2615 return true; 2616 } 2617 return false; 2618 } 2619 2620 private boolean isCursor(dataflow instance, String targetParent) { 2621 if (cursorMap.containsKey(targetParent.toLowerCase())) { 2622 return true; 2623 } 2624 return false; 2625 } 2626 2627 private boolean isVariable(dataflow instance, String targetParent) { 2628 if (variableMap.containsKey(targetParent.toLowerCase())) { 2629 return true; 2630 } 2631 return false; 2632 } 2633 2634 private boolean isFile(dataflow instance, String targetParent) { 2635 if (fileMap.containsKey(targetParent.toLowerCase())) { 2636 return true; 2637 } 2638 return false; 2639 } 2640 2641 private boolean isStage(dataflow instance, String targetParent) { 2642 if (stageMap.containsKey(targetParent.toLowerCase())) { 2643 return true; 2644 } 2645 return false; 2646 } 2647 2648 private boolean isSequence(dataflow instance, String targetParent) { 2649 if (sequenceMap.containsKey(targetParent.toLowerCase())) { 2650 return true; 2651 } 2652 return false; 2653 } 2654 2655 private boolean isDataSource(dataflow instance, String targetParent) { 2656 if (dataSourceMap.containsKey(targetParent.toLowerCase())) { 2657 return true; 2658 } 2659 return false; 2660 } 2661 2662 private boolean isDatabase(dataflow instance, String targetParent) { 2663 if (databaseMap.containsKey(targetParent.toLowerCase())) { 2664 return true; 2665 } 2666 return false; 2667 } 2668 2669 private boolean isSchema(dataflow instance, String targetParent) { 2670 if (schemaMap.containsKey(targetParent.toLowerCase())) { 2671 return true; 2672 } 2673 return false; 2674 } 2675 2676 private boolean isStream(dataflow instance, String targetParent) { 2677 if (streamMap.containsKey(targetParent.toLowerCase())) { 2678 return true; 2679 } 2680 return false; 2681 } 2682 2683 private boolean isTable(dataflow instance, String targetParent) { 2684 if (tableMap.containsKey(targetParent.toLowerCase())) { 2685 if (SQLUtil.isTempTable(tableMap.get(targetParent))) { 2686 if (option.isIgnoreTemporaryTable()) { 2687 return false; 2688 } 2689 } 2690 if (tableMap.get(targetParent).isFunction()) { 2691 if (option != null && option.isSimpleShowFunction()) { 2692 return true; 2693 } else { 2694 return false; 2695 } 2696 } 2697 if (SubType.synonym.name().equals(tableMap.get(targetParent).getSubType())) { 2698 if (option != null && option.isSimpleShowSynonym()) { 2699 return true; 2700 } else { 2701 return false; 2702 } 2703 } 2704 return true; 2705 } else { 2706 return false; 2707 } 2708 } 2709 2710 private void init() { 2711 metadataErrors.clear(); 2712 sqlInfoMap.clear(); 2713 errorInfos.clear(); 2714 dataflow = null; 2715 dataflowString = null; 2716 ModelBindingManager.removeGlobalDatabase(); 2717 ModelBindingManager.removeGlobalSchema(); 2718 ModelBindingManager.removeGlobalVendor(); 2719 ModelBindingManager.removeGlobalSQLEnv(); 2720 ModelBindingManager.removeGlobalHash(); 2721 appendResultSets.clear(); 2722 appendStarColumns.clear(); 2723 appendTableStarColumns.clear(); 2724 modelManager.TABLE_COLUMN_ID = option.getStartId(); 2725 modelManager.RELATION_ID = option.getStartId(); 2726 modelManager.DISPLAY_ID.clear(); 2727 modelManager.DISPLAY_NAME.clear(); 2728 tableIds.clear(); 2729 ModelBindingManager.setGlobalVendor(option.getVendor()); 2730 modelManager.reset(); 2731 } 2732 2733 private String getErrorMessage(TSyntaxError error, String errorType) { 2734 String s = "", hint = "Syntax error"; 2735 if (ErrorInfo.SYNTAX_HINT.equals(errorType)) { 2736 hint = "Syntax hint"; 2737 } 2738 if (error.hint.length() > 0) 2739 hint = error.hint; 2740 s = s + hint + "(" + error.errorno + ") near: " + error.tokentext; 2741 s = s + "(" + error.lineNo; 2742 s = s + "," + error.columnNo + ")"; 2743 return s; 2744 } 2745 2746// boolean OLD_ENABLE_RESOLVER = TBaseType.isEnableResolver(); 2747 private void analyzeAndOutputResult(TGSqlParser sqlparser) { 2748 try { 2749 accessedSubqueries.clear(); 2750 accessedStatements.clear(); 2751 stmtStack.clear(); 2752 viewDDLMap.clear(); 2753 procedureDDLMap.clear(); 2754 structObjectMap.clear(); 2755 try { 2756 if(sqlenv!=null) { 2757 sqlparser.setSqlEnv(sqlenv); 2758 } 2759 int result = sqlparser.parse(); 2760 if (result != 0) { 2761 ArrayList<TSyntaxError> errors = sqlparser.getSyntaxErrors(); 2762 if (errors != null && !errors.isEmpty()) { 2763 for (int i = 0; i < errors.size(); i++) { 2764 TSyntaxError error = errors.get(i); 2765 ErrorInfo errorInfo = new ErrorInfo(); 2766 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 2767 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 2768 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 2769 ModelBindingManager.getGlobalHash())); 2770 String[] segments = error.tokentext.split("\n"); 2771 if (segments.length <= 1) { 2772 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 2773 error.columnNo + error.tokentext.length(), 2774 ModelBindingManager.getGlobalHash())); 2775 } else { 2776 errorInfo.setEndPosition( 2777 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 2778 (long) segments[segments.length - 1].length() + 1, 2779 ModelBindingManager.getGlobalHash())); 2780 } 2781 ; 2782 errorInfo.fillInfo(this); 2783 errorInfos.add(errorInfo); 2784 } 2785 } 2786 } 2787 2788 if (option.getHandleListener() != null) { 2789 option.getHandleListener().endParse(result == 0); 2790 } 2791 } catch (Exception e) { 2792 logger.error("analyze sql failed.", e); 2793 if (option.getHandleListener() != null) { 2794 option.getHandleListener().endParse(false); 2795 } 2796 ErrorInfo errorInfo = new ErrorInfo(); 2797 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 2798 if (e.getMessage() == null) { 2799 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 2800 errorInfo 2801 .setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 2802 } else { 2803 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 2804 } 2805 } else { 2806 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 2807 } 2808 errorInfo.fillInfo(this); 2809 errorInfos.add(errorInfo); 2810 return; 2811 } 2812 2813 2814 TSQLResolver2 resolver = sqlparser.getResolver2(); 2815 if (resolver != null && option.getVendor() == EDbVendor.dbvbigquery) { 2816 ScopeBuildResult buildResult = resolver.getScopeBuildResult(); 2817 List<TObjectName> columns = buildResult.getAllColumnReferences(); 2818 for (TObjectName col : columns) { 2819 structObjectMap.putIfAbsent(col.getSourceTable(), new TObjectNameList()); 2820 structObjectMap.get(col.getSourceTable()).addObjectName(col); 2821 } 2822 } 2823 2824 if (option.getHandleListener() != null) { 2825 option.getHandleListener().startAnalyzeDataFlow(sqlparser); 2826 } 2827 2828 for (int i = 0; i < sqlparser.getSqlstatements().size(); i++) { 2829 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 2830 break; 2831 } 2832 2833 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 2834 if (stmt.getErrorCount() == 0) { 2835 if (stmt.getParentStmt() == null) { 2836 modelManager.collectSqlHash(stmt); 2837 if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema 2838 || stmt instanceof TCreateTableSqlStatement 2839 || stmt instanceof TCreateExternalDataSourceStmt || stmt instanceof TCreateStageStmt 2840 || stmt instanceof TMssqlCreateType 2841 || stmt instanceof TMssqlDeclare 2842 || stmt instanceof TPlsqlCreateType_Placeholder 2843 || stmt instanceof TPlsqlCreateType 2844 || stmt instanceof TPlsqlTableTypeDefStmt 2845 || (stmt instanceof TCreateFunctionStmt && hasDb2ReturnStmt((TCreateFunctionStmt)stmt)) 2846 || (stmt instanceof TMssqlCreateFunction 2847 && (((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null 2848 || ((TMssqlCreateFunction) stmt).getReturnStmt() != null))) { 2849 boolean listen = false; 2850 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 2851 option.getHandleListener().startAnalyzeStatment(stmt); 2852 listen = true; 2853 } 2854 analyzeCustomSqlStmt(stmt); 2855 if (listen && option.getHandleListener() != null) { 2856 option.getHandleListener().endAnalyzeStatment(stmt); 2857 } 2858 } 2859 } 2860 } 2861 } 2862 2863 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 2864 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 2865 break; 2866 } 2867 2868 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 2869 if (stmt.getErrorCount() == 0) { 2870 if (stmt.getParentStmt() == null) { 2871 if (stmt instanceof TUseDatabase 2872 || stmt instanceof TUseSchema 2873 || stmt instanceof TCreateViewSqlStatement 2874 || stmt instanceof TCreateSynonymStmt 2875 || stmt instanceof TStoredProcedureSqlStatement) { 2876 boolean listen = false; 2877 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 2878 option.getHandleListener().startAnalyzeStatment(stmt); 2879 listen = true; 2880 } 2881 if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema) { 2882 analyzeCustomSqlStmt(stmt); 2883 } else if (stmt instanceof TCreateViewSqlStatement) { 2884 TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt; 2885 if(view.getViewName()!=null) { 2886 viewDDLMap.put(DlineageUtil.getTableFullName(view.getViewName().toString()), view); 2887 } 2888 } else if (stmt instanceof TCreateSynonymStmt) { 2889 TCreateSynonymStmt synonym = (TCreateSynonymStmt) stmt; 2890 if(synonym.getSynonymName()!=null) { 2891 viewDDLMap.put(DlineageUtil.getTableFullName(synonym.getSynonymName().toString()), synonym); 2892 } 2893 } else if (stmt instanceof TStoredProcedureSqlStatement) { 2894 TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) stmt; 2895 if(procedure.getStoredProcedureName() == null) { 2896 continue; 2897 } 2898 procedureDDLMap.put(DlineageUtil.getProcedureNameWithArgNum(procedure), procedure); 2899 } 2900 if (listen && option.getHandleListener() != null) { 2901 option.getHandleListener().endAnalyzeStatment(stmt); 2902 } 2903 } 2904 } 2905 } 2906 } 2907 2908 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 2909 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 2910 break; 2911 } 2912 2913 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 2914 if (stmt.getErrorCount() == 0) { 2915 if (stmt.getParentStmt() == null) { 2916 if (stmt instanceof TUseDatabase 2917 || stmt instanceof TUseSchema 2918 || stmt instanceof TCreateViewSqlStatement 2919 || stmt instanceof TCreateSynonymStmt) { 2920 boolean listen = false; 2921 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 2922 option.getHandleListener().startAnalyzeStatment(stmt); 2923 listen = true; 2924 } 2925 analyzeCustomSqlStmt(stmt); 2926 if (listen && option.getHandleListener() != null) { 2927 option.getHandleListener().endAnalyzeStatment(stmt); 2928 } 2929 } 2930 } 2931 } 2932 } 2933 2934 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 2935 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 2936 break; 2937 } 2938 2939 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 2940 if (stmt.getErrorCount() == 0) { 2941 if (stmt.getParentStmt() == null) { 2942 if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema 2943 || stmt instanceof TStoredProcedureSqlStatement) { 2944 boolean listen = false; 2945 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 2946 option.getHandleListener().startAnalyzeStatment(stmt); 2947 listen = true; 2948 } 2949 if (stmt instanceof TPlsqlCreateTrigger) 2950 continue; 2951 analyzeCustomSqlStmt(stmt); 2952 if (listen && option.getHandleListener() != null) { 2953 option.getHandleListener().endAnalyzeStatment(stmt); 2954 } 2955 } 2956 } 2957 } 2958 } 2959 2960 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 2961 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 2962 break; 2963 } 2964 2965 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 2966 2967 if (option.isIgnoreTopSelect()) { 2968 if ((stmt instanceof TSelectSqlStatement && ((TSelectSqlStatement)stmt).getIntoClause() == null && ((TSelectSqlStatement)stmt).getIntoTableClause() == null ) || stmt instanceof TRedshiftDeclare 2969 || stmt instanceof TRedshiftDeclare) { 2970 continue; 2971 } 2972 } 2973 2974 if (stmt.getErrorCount() == 0) { 2975 if (stmt.getParentStmt() == null) { 2976 if (!(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TCreateStageStmt) 2977 && !(stmt instanceof TCreateExternalDataSourceStmt) 2978 && !(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TMssqlDeclare) 2979 && !(stmt instanceof TMssqlCreateFunction 2980 && ((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null)) { 2981 boolean listen = false; 2982 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 2983 option.getHandleListener().startAnalyzeStatment(stmt); 2984 listen = true; 2985 } 2986 analyzeCustomSqlStmt(stmt); 2987 if (listen && option.getHandleListener() != null) { 2988 option.getHandleListener().endAnalyzeStatment(stmt); 2989 } 2990 } 2991 } 2992 } 2993 } 2994 2995 if (option.getHandleListener() != null) { 2996 option.getHandleListener().endAnalyzeDataFlow(sqlparser); 2997 } 2998 2999 // Finalize pipelined function stitching after all passes 3000 if (!modelManager.getPendingPipelinedCallSites().isEmpty() && sqlparser.getSqlstatements().size() > 0 && pipelinedAnalyzer != null) { 3001 TCustomSqlStatement lastStmt = sqlparser.getSqlstatements().get(sqlparser.getSqlstatements().size() - 1); 3002 stmtStack.push(lastStmt); 3003 try { 3004 pipelinedAnalyzer.stitchPendingCallSites(); 3005 } catch (Exception ex) { 3006 // Don't let pipelined stitching failure break main flow 3007 } finally { 3008 stmtStack.pop(); 3009 } 3010 } 3011 } catch (Throwable e) { 3012 logger.error("analyze sql failed.", e); 3013 ErrorInfo errorInfo = new ErrorInfo(); 3014 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 3015 if (e.getMessage() == null) { 3016 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 3017 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 3018 } else { 3019 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 3020 } 3021 } else { 3022 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 3023 } 3024 errorInfo.fillInfo(this); 3025 errorInfos.add(errorInfo); 3026 } 3027 3028 } 3029 3030 private boolean hasDb2ReturnStmt(TCreateFunctionStmt stmt) { 3031 if (stmt.getReturnStmt() != null) { 3032 return true; 3033 } 3034 if (stmt.getBodyStatements() != null) { 3035 for (int i = 0; i < stmt.getBodyStatements().size(); i++) { 3036 if(stmt.getBodyStatements().get(i) instanceof TDb2ReturnStmt) { 3037 return true; 3038 } 3039 } 3040 } 3041 return false; 3042 } 3043 3044 private void analyzeCustomSqlStmt(TCustomSqlStatement stmt) { 3045 if (!accessedStatements.contains(stmt)) { 3046 accessedStatements.add(stmt); 3047 } else if (!(stmt instanceof TUseDatabase || stmt instanceof TUseSchema)) { 3048 return; 3049 } 3050 3051 ArrayList<TSyntaxError> errors = stmt.getSyntaxHints(); 3052 if (errors != null && !errors.isEmpty()) { 3053 for (int i = 0; i < errors.size(); i++) { 3054 TSyntaxError error = errors.get(i); 3055 ErrorInfo errorInfo = new ErrorInfo(); 3056 errorInfo.setErrorType(ErrorInfo.SYNTAX_HINT); 3057 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_HINT)); 3058 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3059 ModelBindingManager.getGlobalHash())); 3060 String[] segments = error.tokentext.split("\n"); 3061 if (segments.length == 1) { 3062 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3063 error.columnNo + error.tokentext.length(), ModelBindingManager.getGlobalHash())); 3064 } else { 3065 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3066 (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash())); 3067 } 3068 errorInfo.fillInfo(this); 3069 errorInfos.add(errorInfo); 3070 } 3071 } 3072 3073 if (option.getAnalyzeMode() == AnalyzeMode.dynamic) { 3074 if (!(stmt instanceof TStoredProcedureSqlStatement 3075 || stmt instanceof TExecuteSqlStatement 3076 || stmt instanceof TMssqlExecute 3077 || stmt instanceof TExecImmeStmt)) { 3078 return; 3079 } 3080 } 3081 3082 if(DlineageUtil.getTopStmt(stmt) == stmt){ 3083 modelManager.collectSqlHash(stmt); 3084 } 3085 3086 try { 3087 if (stmt instanceof TUseDatabase) { 3088 if (((TUseDatabase) stmt).getDatabaseName() != null) { 3089 ModelBindingManager.setGlobalDatabase(((TUseDatabase) stmt).getDatabaseName().toString()); 3090 } 3091 } else if (stmt instanceof TUseSchema) { 3092 if (((TUseSchema) stmt).getSchemaName() != null) { 3093 String schemaName = ((TUseSchema) stmt).getSchemaName().toString(); 3094 List<String> splits = SQLUtil.parseNames(schemaName); 3095 if (splits.size() == 1) { 3096 ModelBindingManager.setGlobalSchema(schemaName); 3097 } else if (splits.size() > 1) { 3098 ModelBindingManager.setGlobalSchema(splits.get(splits.size() - 1)); 3099 ModelBindingManager.setGlobalDatabase(splits.get(splits.size() - 2)); 3100 } 3101 } 3102 } else if (stmt instanceof TPlsqlRecordTypeDefStmt) { 3103 this.stmtStack.push(stmt); 3104 this.analyzePlsqlRecordTypeDefStmt((TPlsqlRecordTypeDefStmt) stmt); 3105 this.stmtStack.pop(); 3106 } else if (stmt instanceof TPlsqlCreateType_Placeholder) { 3107 this.stmtStack.push(stmt); 3108 TPlsqlCreateType_Placeholder placeholder = (TPlsqlCreateType_Placeholder) stmt; 3109 if (placeholder.getObjectStatement() != null && pipelinedAnalyzer != null) { 3110 this.pipelinedAnalyzer.indexObjectType(placeholder.getObjectStatement()); 3111 } 3112 if (placeholder.getNestedTableStatement() != null) { 3113 if (pipelinedAnalyzer != null) { 3114 this.pipelinedAnalyzer.indexCollectionType(placeholder.getNestedTableStatement()); 3115 } 3116 this.analyzePlsqlTableTypeDefStmt(placeholder.getNestedTableStatement()); 3117 } 3118 this.stmtStack.pop(); 3119 } else if (stmt instanceof TPlsqlCreateType) { 3120 this.stmtStack.push(stmt); 3121 if (pipelinedAnalyzer != null) { 3122 this.pipelinedAnalyzer.indexObjectType((TPlsqlCreateType) stmt); 3123 } 3124 this.stmtStack.pop(); 3125 } else if (stmt instanceof TPlsqlTableTypeDefStmt) { 3126 this.stmtStack.push(stmt); 3127 this.analyzePlsqlTableTypeDefStmt((TPlsqlTableTypeDefStmt) stmt); 3128 if (pipelinedAnalyzer != null) { 3129 this.pipelinedAnalyzer.indexCollectionType((TPlsqlTableTypeDefStmt) stmt); 3130 } 3131 this.stmtStack.pop(); 3132 } else if (stmt instanceof TStoredProcedureSqlStatement) { 3133 this.stmtStack.push(stmt); 3134 this.analyzeStoredProcedureStmt((TStoredProcedureSqlStatement) stmt); 3135 this.stmtStack.pop(); 3136 } else if (stmt instanceof TCreateTableSqlStatement) { 3137 stmtStack.push(stmt); 3138 analyzeCreateTableStmt((TCreateTableSqlStatement) stmt); 3139 stmtStack.pop(); 3140 } else if (stmt instanceof TCreateStageStmt) { 3141 stmtStack.push(stmt); 3142 analyzeCreateStageStmt((TCreateStageStmt) stmt); 3143 stmtStack.pop(); 3144 } else if (stmt instanceof TCreateExternalDataSourceStmt) { 3145 stmtStack.push(stmt); 3146 analyzeCreateExternalDataSourceStmt((TCreateExternalDataSourceStmt) stmt); 3147 stmtStack.pop(); 3148 } else if (stmt instanceof TCreateStreamStmt) { 3149 stmtStack.push(stmt); 3150 analyzeCreateStreamStmt((TCreateStreamStmt) stmt); 3151 stmtStack.pop(); 3152 } else if (stmt instanceof TSelectSqlStatement) { 3153 analyzeSelectStmt((TSelectSqlStatement) stmt); 3154 } else if (stmt instanceof TDropTableSqlStatement) { 3155 stmtStack.push(stmt); 3156 analyzeDropTableStmt((TDropTableSqlStatement) stmt); 3157 stmtStack.pop(); 3158 } else if (stmt instanceof TTruncateStatement) { 3159 stmtStack.push(stmt); 3160 analyzeTruncateTableStmt((TTruncateStatement) stmt); 3161 stmtStack.pop(); 3162 } else if (stmt instanceof TCreateMaterializedSqlStatement) { 3163 stmtStack.push(stmt); 3164 TCreateMaterializedSqlStatement view = (TCreateMaterializedSqlStatement) stmt; 3165 analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName()); 3166 stmtStack.pop(); 3167 } else if (stmt instanceof TCreateViewSqlStatement) { 3168 stmtStack.push(stmt); 3169 TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt; 3170 analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName()); 3171 stmtStack.pop(); 3172 } else if(stmt instanceof TDb2SqlVariableDeclaration){ 3173 stmtStack.push(stmt); 3174 analyzeDb2Declare((TDb2SqlVariableDeclaration)stmt); 3175 stmtStack.pop(); 3176 } else if (stmt instanceof TMssqlCreateType) { 3177 stmtStack.push(stmt); 3178 TMssqlCreateType createType = (TMssqlCreateType) stmt; 3179 analyzeMssqlCreateType(createType); 3180 stmtStack.pop(); 3181 } else if (stmt instanceof TMssqlDeclare) { 3182 stmtStack.push(stmt); 3183 TMssqlDeclare declare = (TMssqlDeclare) stmt; 3184 analyzeMssqlDeclare(declare); 3185 stmtStack.pop(); 3186 } else if (stmt instanceof TInsertSqlStatement) { 3187 stmtStack.push(stmt); 3188 TInsertSqlStatement insert = (TInsertSqlStatement)stmt; 3189 analyzeInsertStmt(insert); 3190 if(insert.getMultiInsertStatements()!=null) { 3191 for(int i=0;i<insert.getMultiInsertStatements().size();i++) { 3192 analyzeInsertStmt(insert.getMultiInsertStatements().get(i)); 3193 } 3194 } 3195 stmtStack.pop(); 3196 } else if (stmt instanceof TRedshiftCopy) { 3197 stmtStack.push(stmt); 3198 analyzeRedshiftCopyStmt((TRedshiftCopy) stmt); 3199 stmtStack.pop(); 3200 } else if (stmt instanceof TSnowflakeCopyIntoStmt) { 3201 stmtStack.push(stmt); 3202 analyzeCopyIntoStmt((TSnowflakeCopyIntoStmt) stmt); 3203 stmtStack.pop(); 3204 } else if (stmt instanceof TUnloadStmt) { 3205 stmtStack.push(stmt); 3206 analyzeUnloadStmt((TUnloadStmt) stmt); 3207 stmtStack.pop(); 3208 } else if (stmt instanceof TUpdateSqlStatement) { 3209 stmtStack.push(stmt); 3210 analyzeUpdateStmt((TUpdateSqlStatement) stmt); 3211 stmtStack.pop(); 3212 } else if (stmt instanceof TMergeSqlStatement) { 3213 stmtStack.push(stmt); 3214 analyzeMergeStmt((TMergeSqlStatement) stmt); 3215 stmtStack.pop(); 3216 } else if (stmt instanceof TDeleteSqlStatement) { 3217 stmtStack.push(stmt); 3218 analyzeDeleteStmt((TDeleteSqlStatement) stmt); 3219 stmtStack.pop(); 3220 } else if (stmt instanceof TCursorDeclStmt) { 3221 stmtStack.push(stmt); 3222 analyzeCursorDeclStmt((TCursorDeclStmt) stmt); 3223 stmtStack.pop(); 3224 } else if (stmt instanceof TFetchStmt) { 3225 stmtStack.push(stmt); 3226 analyzeFetchStmt((TFetchStmt) stmt); 3227 stmtStack.pop(); 3228 } else if (stmt instanceof TMssqlFetch) { 3229 stmtStack.push(stmt); 3230 analyzeFetchStmt((TMssqlFetch) stmt); 3231 stmtStack.pop(); 3232 } else if (stmt instanceof TForStmt) { 3233 stmtStack.push(stmt); 3234 analyzeForStmt((TForStmt) stmt); 3235 stmtStack.pop(); 3236 } else if (stmt instanceof TOpenforStmt) { 3237 stmtStack.push(stmt); 3238 analyzeOpenForStmt((TOpenforStmt) stmt); 3239 stmtStack.pop(); 3240 } else if (stmt instanceof TLoopStmt) { 3241 stmtStack.push(stmt); 3242 analyzeLoopStmt((TLoopStmt) stmt); 3243 stmtStack.pop(); 3244 } else if (stmt instanceof TAssignStmt) { 3245 stmtStack.push(stmt); 3246 analyzeAssignStmt((TAssignStmt) stmt); 3247 stmtStack.pop(); 3248 } else if (stmt instanceof TSetStmt) { 3249 stmtStack.push(stmt); 3250 analyzeSetStmt((TSetStmt) stmt); 3251 stmtStack.pop(); 3252 } else if (stmt instanceof TMssqlSet) { 3253 stmtStack.push(stmt); 3254 analyzeMssqlSetStmt((TMssqlSet) stmt); 3255 stmtStack.pop(); 3256 } else if (stmt instanceof TVarDeclStmt) { 3257 stmtStack.push(stmt); 3258 analyzeVarDeclStmt((TVarDeclStmt) stmt); 3259 stmtStack.pop(); 3260 } else if (stmt instanceof TCreateDatabaseSqlStatement) { 3261 stmtStack.push(stmt); 3262 analyzeCloneDatabaseStmt((TCreateDatabaseSqlStatement) stmt); 3263 stmtStack.pop(); 3264 } else if (stmt instanceof TCreateSchemaSqlStatement) { 3265 stmtStack.push(stmt); 3266 analyzeCloneSchemaStmt((TCreateSchemaSqlStatement) stmt); 3267 stmtStack.pop(); 3268 } else if (stmt instanceof TAlterTableStatement) { 3269 stmtStack.push(stmt); 3270 analyzeAlterTableStmt((TAlterTableStatement) stmt); 3271 stmtStack.pop(); 3272 } else if (stmt instanceof TAlterViewStatement) { 3273 stmtStack.push(stmt); 3274 analyzeAlterViewStmt((TAlterViewStatement) stmt); 3275 stmtStack.pop(); 3276 } else if (stmt instanceof TRenameStmt) { 3277 stmtStack.push(stmt); 3278 analyzeRenameStmt((TRenameStmt) stmt); 3279 stmtStack.pop(); 3280 } else if (stmt instanceof TCreateSynonymStmt) { 3281 stmtStack.push(stmt); 3282 analyzeCreateSynonymStmt((TCreateSynonymStmt) stmt); 3283 stmtStack.pop(); 3284 } else if (stmt instanceof TLoadDataStmt) { 3285 stmtStack.push(stmt); 3286 analyzeLoadDataStmt((TLoadDataStmt) stmt); 3287 stmtStack.pop(); 3288 } else if (stmt instanceof THiveLoad) { 3289 stmtStack.push(stmt); 3290 analyzeHiveLoadStmt((THiveLoad) stmt); 3291 stmtStack.pop(); 3292 } else if (stmt instanceof TDb2ReturnStmt) { 3293 stmtStack.push(stmt); 3294 analyzeDb2ReturnStmt((TDb2ReturnStmt) stmt); 3295 stmtStack.pop(); 3296 } else if (stmt instanceof TReturnStmt) { 3297 stmtStack.push(stmt); 3298 analyzeReturnStmt((TReturnStmt) stmt); 3299 stmtStack.pop(); 3300 } else if (stmt instanceof TMssqlReturn) { 3301 stmtStack.push(stmt); 3302 analyzeMssqlReturnStmt((TMssqlReturn) stmt); 3303 stmtStack.pop(); 3304 } else if (stmt instanceof TExecuteSqlStatement) { 3305 String sqlText = ((TExecuteSqlStatement) stmt).getPreparedSqlText(); 3306 if(sqlText == null) { 3307 sqlText = ((TExecuteSqlStatement) stmt).getSqlText(); 3308 } 3309 if (sqlText != null) { 3310 modelManager.collectDynamicSqlHash(stmt); 3311 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 3312 sqlparser.sqltext = SQLUtil.trimColumnStringQuote(sqlText); 3313 int result = sqlparser.parse(); 3314 if (result != 0) { 3315 errors = sqlparser.getSyntaxErrors(); 3316 if (errors != null && !errors.isEmpty()) { 3317 for (int i = 0; i < errors.size(); i++) { 3318 TSyntaxError error = errors.get(i); 3319 ErrorInfo errorInfo = new ErrorInfo(); 3320 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 3321 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 3322 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3323 ModelBindingManager.getGlobalHash())); 3324 String[] segments = error.tokentext.split("\n"); 3325 if (segments.length == 1) { 3326 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3327 error.columnNo + error.tokentext.length(), 3328 ModelBindingManager.getGlobalHash())); 3329 } else { 3330 errorInfo.setEndPosition( 3331 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3332 (long) segments[segments.length - 1].length() + 1, 3333 ModelBindingManager.getGlobalHash())); 3334 } 3335 errorInfo.fillInfo(this); 3336 errorInfos.add(errorInfo); 3337 } 3338 } 3339 } else if (sqlparser.sqlstatements != null) { 3340 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3341 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 3342 } 3343 } 3344 } 3345 else if (((TExecuteSqlStatement) stmt).getStmtString() != null) { 3346 modelManager.collectDynamicSqlHash(stmt); 3347 } 3348 } else if (stmt instanceof TMssqlExecute) { 3349 TMssqlExecute executeStmt = (TMssqlExecute)stmt; 3350 if (executeStmt.getSqlText() != null) { 3351 modelManager.collectDynamicSqlHash(stmt); 3352 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 3353 sqlparser.sqltext = ((TMssqlExecute) stmt).getSqlText(); 3354 int result = sqlparser.parse(); 3355 if (result != 0) { 3356 errors = sqlparser.getSyntaxErrors(); 3357 if (errors != null && !errors.isEmpty()) { 3358 for (int i = 0; i < errors.size(); i++) { 3359 TSyntaxError error = errors.get(i); 3360 ErrorInfo errorInfo = new ErrorInfo(); 3361 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 3362 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 3363 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3364 ModelBindingManager.getGlobalHash())); 3365 String[] segments = error.tokentext.split("\n"); 3366 if (segments.length == 1) { 3367 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3368 error.columnNo + error.tokentext.length(), 3369 ModelBindingManager.getGlobalHash())); 3370 } else { 3371 errorInfo.setEndPosition( 3372 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3373 (long) segments[segments.length - 1].length() + 1, 3374 ModelBindingManager.getGlobalHash())); 3375 } 3376 errorInfo.fillInfo(this); 3377 errorInfos.add(errorInfo); 3378 } 3379 } 3380 } else if (sqlparser.sqlstatements != null) { 3381 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3382 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 3383 } 3384 } 3385 } else if (executeStmt.getModuleName() != null) { 3386 stmtStack.push(stmt); 3387 analyzeMssqlExecute(executeStmt); 3388 stmtStack.pop(); 3389 } 3390 } else if (stmt instanceof TExecImmeStmt) { 3391 TExecImmeStmt execImmeStmt = (TExecImmeStmt) stmt; 3392 modelManager.collectDynamicSqlHash(stmt); 3393 synchronized (DataFlowAnalyzer.class) { 3394 TStatementList stmts = execImmeStmt.getDynamicStatements(); 3395 if (stmts != null && stmts.size() > 0) { 3396 for (int i = 0; i < stmts.size(); i++) { 3397 analyzeCustomSqlStmt(stmts.get(i)); 3398 } 3399 } 3400 3401 // Only re-parse the raw dynamic SQL when getDynamicStatements() 3402 // produced nothing. getDynamicStatements() already parses and 3403 // analyzes the fragment with coordinates remapped back to the 3404 // original file position; re-parsing it here with a fresh parser 3405 // would analyze the same SQL a second time and emit duplicate 3406 // hints/lineage carrying fragment-relative (un-remapped) 3407 // coordinates. This fallback still covers the case where 3408 // getDynamicStatements() failed (e.g. dynamic SQL syntax error), 3409 // reporting the parse error below. 3410 String dynamicSql = (stmts == null || stmts.size() == 0) ? execImmeStmt.getDynamicSQL() : null; 3411 if (!SQLUtil.isEmpty(dynamicSql)) { 3412 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 3413 sqlparser.sqltext = dynamicSql; 3414 int result = sqlparser.parse(); 3415 // This fresh parse runs the dynamic SQL un-padded, so its 3416 // coordinates are relative to the fragment (first char at 3417 // line 1). Shift them back to the position the fragment 3418 // occupies in the original file, mirroring the shift 3419 // TExecImmeStmt.getDynamicStatements() applies; otherwise 3420 // fallback parse errors for EXECUTE IMMEDIATE text located 3421 // later in the file would report fragment-relative lines. 3422 if (execImmeStmt.getDynamicStringExpr() != null 3423 && execImmeStmt.getDynamicStringExpr().getPlainTextLineNo() != -1) { 3424 int deltaLine = (int) execImmeStmt.getDynamicStringExpr().getPlainTextLineNo() - 1; 3425 int deltaColumn = (int) execImmeStmt.getDynamicStringExpr().getPlainTextColumnNo(); 3426 if ((deltaLine != 0 || deltaColumn != 0) && sqlparser.getSyntaxErrors() != null) { 3427 for (int ei = 0; ei < sqlparser.getSyntaxErrors().size(); ei++) { 3428 TSyntaxError dynErr = sqlparser.getSyntaxErrors().get(ei); 3429 if (dynErr == null) continue; 3430 boolean onFirstLine = (dynErr.lineNo == 1); 3431 dynErr.lineNo += deltaLine; 3432 if (onFirstLine) dynErr.columnNo += deltaColumn; 3433 } 3434 } 3435 } 3436 if (result != 0) { 3437 errors = sqlparser.getSyntaxErrors(); 3438 if (errors != null && !errors.isEmpty()) { 3439 for (int i = 0; i < errors.size(); i++) { 3440 TSyntaxError error = errors.get(i); 3441 ErrorInfo errorInfo = new ErrorInfo(); 3442 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 3443 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 3444 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3445 ModelBindingManager.getGlobalHash())); 3446 String[] segments = error.tokentext.split("\n"); 3447 if (segments.length == 1) { 3448 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3449 error.columnNo + error.tokentext.length(), 3450 ModelBindingManager.getGlobalHash())); 3451 } else { 3452 errorInfo.setEndPosition( 3453 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3454 (long) segments[segments.length - 1].length() + 1, 3455 ModelBindingManager.getGlobalHash())); 3456 } 3457 errorInfo.fillInfo(this); 3458 errorInfos.add(errorInfo); 3459 } 3460 } 3461 } else if (sqlparser.sqlstatements != null) { 3462 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3463 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 3464 } 3465 } 3466 } 3467 } 3468 } else if (stmt instanceof TCallStatement) { 3469 TCallStatement callStmt = (TCallStatement)stmt; 3470 stmtStack.push(stmt); 3471 analyzeCallStmt(callStmt); 3472 stmtStack.pop(); 3473 } else if (stmt instanceof TBasicStmt) { 3474 TBasicStmt oracleBasicStmt = (TBasicStmt) stmt; 3475 stmtStack.push(stmt); 3476 analyzeOracleBasicStmt(oracleBasicStmt); 3477 stmtStack.pop(); 3478 } else if (stmt instanceof TIfStmt) { 3479 TIfStmt ifStmt = (TIfStmt) stmt; 3480 stmtStack.push(stmt); 3481 analyzeIfStmt(ifStmt); 3482 stmtStack.pop(); 3483 } else if (stmt instanceof TElsifStmt) { 3484 TElsifStmt elsIfStmt = (TElsifStmt) stmt; 3485 stmtStack.push(stmt); 3486 analyzeElsIfStmt(elsIfStmt); 3487 stmtStack.pop(); 3488 } else if (stmt.getStatements() != null && stmt.getStatements().size() > 0) { 3489 for (int i = 0; i < stmt.getStatements().size(); i++) { 3490 analyzeCustomSqlStmt(stmt.getStatements().get(i)); 3491 } 3492 } else if (stmt instanceof TCreateIndexSqlStatement) { 3493 stmtStack.push(stmt); 3494 analyzeCreateIndexStageStmt((TCreateIndexSqlStatement) stmt); 3495 stmtStack.pop(); 3496 } else if (stmt instanceof gudusoft.gsqlparser.stmt.mdx.TMdxSelect) { 3497 stmtStack.push(stmt); 3498 analyzeMdxSelectStmt((gudusoft.gsqlparser.stmt.mdx.TMdxSelect) stmt); 3499 stmtStack.pop(); 3500 } else if (stmt instanceof TPowerQueryDocumentStmt) { 3501 stmtStack.push(stmt); 3502 analyzePowerQueryDocumentStmt((TPowerQueryDocumentStmt) stmt); 3503 stmtStack.pop(); 3504 } 3505 } catch (Exception e) { 3506 StringBuffer errorMessage = new StringBuffer(); 3507 errorMessage.append("analyze sql stmt failed, "); 3508 if (stmt.getStartToken() != null) { 3509 errorMessage.append("line: " + stmt.getStartToken().lineNo + ", column: " + stmt.getStartToken().columnNo).append(", "); 3510 } 3511 if (stmt.getGsqlparser() != null && !SQLUtil.isEmpty(stmt.getGsqlparser().sqlfilename)) { 3512 errorMessage.append("file: "+ stmt.getGsqlparser().sqlfilename).append(", "); 3513 } 3514 if (stmt.toString() != null) { 3515 errorMessage.append("sql:\n" + stmt.toString()); 3516 } 3517 logger.error(errorMessage.toString(), e); 3518 ErrorInfo errorInfo = new ErrorInfo(); 3519 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 3520 if (e.getMessage() == null) { 3521 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 3522 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 3523 } else { 3524 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 3525 } 3526 } else { 3527 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 3528 } 3529 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 3530 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 3531 String[] segments = stmt.getEndToken().getAstext().split("\n", -1); 3532 if (segments.length == 1) { 3533 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 3534 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 3535 ModelBindingManager.getGlobalHash())); 3536 } else { 3537 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo + segments.length - 1, 3538 (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash())); 3539 } 3540 errorInfo.fillInfo(this); 3541 errorInfos.add(errorInfo); 3542 } 3543 } 3544 3545 private void analyzePlsqlRecordTypeDefStmt(TPlsqlRecordTypeDefStmt stmt) { 3546 TObjectName typeName = stmt.getTypeName(); 3547 Variable variable = modelFactory.createVariable(typeName); 3548 variable.setSubType(SubType.record_type); 3549 3550 if (stmt.getFieldDeclarations() != null) { 3551 for (int i = 0; i < stmt.getFieldDeclarations().size(); i++) { 3552 TParameterDeclaration param = stmt.getFieldDeclarations().getParameterDeclarationItem(i); 3553 String dataTypeName = param.getDataType().getDataTypeName(); 3554 TObjectName columnName = param.getParameterName(); 3555 TableColumn variableProperty = modelFactory.createTableColumn(variable, columnName, true); 3556 if(dataTypeName.indexOf(".")!=-1) { 3557 String tableName = dataTypeName.substring(0, dataTypeName.lastIndexOf(".")); 3558 Table table = modelFactory.createTableByName(tableName, true); 3559 if(table!=null) { 3560 TableColumn tableColumn = modelFactory.createInsertTableColumn(table, dataTypeName); 3561 if (tableColumn != null) { 3562 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 3563 relation.setEffectType(EffectType.rowtype); 3564 relation.setTarget(new TableColumnRelationshipElement(variableProperty)); 3565 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 3566 } 3567 } 3568 } 3569 } 3570 variable.setDetermined(true); 3571 } 3572 else { 3573 TObjectName starColumn = new TObjectName(); 3574 starColumn.setString("*"); 3575 } 3576 } 3577 3578 private void analyzePlsqlTableTypeDefStmt(TPlsqlTableTypeDefStmt stmt) { 3579 TTypeName typeName = stmt.getElementDataType(); 3580 if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) { 3581 Variable cursorVariable = modelFactory.createVariable(stmt.getTypeName()); 3582 cursorVariable.setSubType(SubType.record_type); 3583 3584 Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false); 3585 if(!variableTable.isCreateTable()) { 3586 TObjectName starColumn1 = new TObjectName(); 3587 starColumn1.setString("*"); 3588 TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true); 3589 variableTableStarColumn.setShowStar(false); 3590 variableTableStarColumn.setExpandStar(true); 3591 3592 TObjectName starColumn = new TObjectName(); 3593 starColumn.setString("*"); 3594 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 3595 variableProperty.setShowStar(false); 3596 variableProperty.setExpandStar(true); 3597 3598 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 3599 dataflowRelation.setEffectType(EffectType.rowtype); 3600 dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn)); 3601 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 3602 } else { 3603 for (TableColumn sourceColumn : variableTable.getColumns()) { 3604 String columnName = sourceColumn.getName(); 3605 TObjectName targetColumn = new TObjectName(); 3606 targetColumn.setString(columnName); 3607 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true); 3608 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 3609 dataflowRelation.setEffectType(EffectType.rowtype); 3610 dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn)); 3611 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 3612 } 3613 } 3614 } 3615 } 3616 3617 private void analyzeMssqlCreateType(TMssqlCreateType createType) { 3618 3619 } 3620 3621 private void analyzeMssqlExecute(TMssqlExecute executeStmt) { 3622 if (executeStmt.getModuleName() != null) { 3623 TObjectName module = executeStmt.getModuleName(); 3624 if(module.toString().toLowerCase().endsWith("sp_rename")) { 3625 String oldTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString()); 3626 Table oldNameTableModel = modelFactory.createTableByName(oldTableName, true); 3627 List<String> oldTableNames = SQLUtil.parseNames(oldNameTableModel.getName()); 3628 TObjectName oldStarColumn = new TObjectName(); 3629 oldStarColumn.setString("*"); 3630 TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true); 3631 3632 String newTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(1).toString()); 3633 List<String> newTableNames = SQLUtil.parseNames(newTableName); 3634 if (oldTableNames.size() > newTableNames.size()) { 3635 for (int i = oldTableNames.size() - newTableNames.size() - 1; i >= 0; i--) { 3636 newTableName = (oldTableNames.get(i) + ".") + newTableName; 3637 } 3638 } 3639 3640 Table newNameTableModel = modelFactory.createTableByName(newTableName, true); 3641 TObjectName newStarColumn = new TObjectName(); 3642 newStarColumn.setString("*"); 3643 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true); 3644 3645 Process process = modelFactory.createProcess(executeStmt); 3646 newNameTableModel.addProcess(process); 3647 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 3648 relation.setEffectType(EffectType.rename_table); 3649 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 3650 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 3651 relation.setProcess(process); 3652 3653 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 3654 oldTableStarColumn.setShowStar(false); 3655 relation.setShowStarRelation(false); 3656 } 3657 3658 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 3659 newTableStarColumn.setShowStar(false); 3660 relation.setShowStarRelation(false); 3661 } 3662 } 3663 else if(module.toString().toLowerCase().endsWith("sp_executesql")) { 3664 String sql = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString()); 3665 if(sql.startsWith("N")) { 3666 sql = SQLUtil.trimColumnStringQuote(sql.substring(1)); 3667 } 3668 executeDynamicSql(sql); 3669 } 3670 else { 3671 int argumentSize = executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size(); 3672 String procedureNameWithArgSize = module.toString() + "(" + argumentSize + ")"; 3673 if (argumentSize <= 0 || !DlineageUtil.supportFunctionOverride(option.getVendor())) { 3674 procedureNameWithArgSize = module.toString(); 3675 } 3676 if (procedureDDLMap.containsKey(procedureNameWithArgSize)) { 3677 analyzeCustomSqlStmt(procedureDDLMap.get(procedureNameWithArgSize)); 3678 } 3679 Procedure procedure = modelFactory.createProcedureByName(module, executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size()); 3680 String procedureParent = getProcedureParentName(executeStmt); 3681 if (procedureParent != null) { 3682 Procedure caller = modelManager 3683 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3684 if (caller != null) { 3685 CallRelationship callRelation = modelFactory.createCallRelation(); 3686 callRelation.setCallObject(executeStmt); 3687 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3688 callRelation.addSource(new ProcedureRelationshipElement(procedure)); 3689 if(isBuiltInFunctionName(module) || isKeyword(module)){ 3690 callRelation.setBuiltIn(true); 3691 } 3692 } 3693 } 3694 3695 if (procedure.getArguments() != null) { 3696 for (int i = 0; i < procedure.getArguments().size(); i++) { 3697 Argument argument = procedure.getArguments().get(i); 3698 Variable variable = modelFactory.createVariable(procedure, argument.getName(), false); 3699 if (variable != null) { 3700 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 3701 Transform transform = new Transform(); 3702 transform.setType(Transform.FUNCTION); 3703 transform.setCode(module); 3704 variable.getColumns().get(0).setTransform(transform); 3705 } 3706 Process process = modelFactory.createProcess(executeStmt); 3707 variable.addProcess(process); 3708 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), executeStmt, argument.getName(), i, process); 3709 } 3710 } 3711 } 3712 } 3713 } 3714 } 3715 3716 private void analyzeDropTableStmt(TDropTableSqlStatement stmt) { 3717 TTable dropTable = stmt.getTargetTable(); 3718 if(dropTable == null) { 3719 return; 3720 } 3721 Table tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(dropTable.getTableName().toString())); 3722 if(tableModel!=null) { 3723 modelManager.dropTable(tableModel); 3724 } 3725 3726 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 3727 tableModel = modelFactory.createTable(dropTable); 3728 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 3729 crudRelationship.setTarget(new TableRelationshipElement(tableModel)); 3730 crudRelationship.setEffectType(EffectType.drop_table); 3731 } 3732 } 3733 3734 private void analyzeTruncateTableStmt(TTruncateStatement stmt) { 3735 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 3736 TObjectName table = stmt.getTableName(); 3737 Table tableModel = modelFactory.createTableByName(table); 3738 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 3739 crudRelationship.setTarget(new TableRelationshipElement(tableModel)); 3740 crudRelationship.setEffectType(EffectType.truncate_table); 3741 } 3742 } 3743 3744 private void analyzeCallStmt(TCallStatement callStmt) { 3745 if (callStmt.getRoutineExpr() != null && callStmt.getRoutineExpr().getFunctionCall() != null) { 3746 3747 TFunctionCall functionCall = callStmt.getRoutineExpr().getFunctionCall(); 3748 Procedure callee = modelManager.getProcedureByName( 3749 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3750 if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 3751 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3752 callee = modelManager.getProcedureByName(DlineageUtil 3753 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3754 } 3755 if (callee != null) { 3756 String procedureParent = getProcedureParentName(callStmt); 3757 if (procedureParent != null) { 3758 Procedure caller = modelManager 3759 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3760 if (caller != null) { 3761 CallRelationship callRelation = modelFactory.createCallRelation(); 3762 callRelation.setCallObject(callStmt); 3763 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3764 callRelation.addSource(new ProcedureRelationshipElement(callee)); 3765 if (isBuiltInFunctionName(functionCall.getFunctionName()) 3766 || isKeyword(functionCall.getFunctionName())) { 3767 callRelation.setBuiltIn(true); 3768 } 3769 } 3770 } 3771 if (callee.getArguments() != null) { 3772 for (int i = 0; i < callee.getArguments().size(); i++) { 3773 Argument argument = callee.getArguments().get(i); 3774 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 3775 if (variable != null) { 3776 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 3777 Transform transform = new Transform(); 3778 transform.setType(Transform.FUNCTION); 3779 transform.setCode(functionCall); 3780 variable.getColumns().get(0).setTransform(transform); 3781 } 3782 Process process = modelFactory.createProcess(callStmt); 3783 variable.addProcess(process); 3784 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, 3785 process); 3786 } 3787 } 3788 } 3789 } else { 3790 Function function = (Function) createFunction(functionCall); 3791 String procedureParent = getProcedureParentName(callStmt); 3792 if (procedureParent != null) { 3793 Procedure caller = modelManager 3794 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3795 if (caller != null) { 3796 CallRelationship callRelation = modelFactory.createCallRelation(); 3797 callRelation.setCallObject(callStmt); 3798 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3799 callRelation.addSource(new FunctionRelationshipElement(function)); 3800 if (isBuiltInFunctionName(functionCall.getFunctionName()) 3801 || isKeyword(functionCall.getFunctionName())) { 3802 callRelation.setBuiltIn(true); 3803 } 3804 } 3805 } 3806 } 3807 } 3808 else if (callStmt.getRoutineName() != null) { 3809 TObjectName function = callStmt.getRoutineName(); 3810 String functionName = function.toString(); 3811 Procedure callee = modelManager.getProcedureByName( 3812 DlineageUtil.getIdentifierNormalTableName(functionName)); 3813 if (callee == null && procedureDDLMap.containsKey(functionName)) { 3814 analyzeCustomSqlStmt(procedureDDLMap.get(functionName)); 3815 callee = modelManager.getProcedureByName(functionName); 3816 } 3817 if (callee != null) { 3818 String procedureParent = getProcedureParentName(callStmt); 3819 if (procedureParent != null) { 3820 Procedure caller = modelManager 3821 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3822 if (caller != null) { 3823 CallRelationship callRelation = modelFactory.createCallRelation(); 3824 callRelation.setCallObject(callStmt); 3825 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3826 callRelation.addSource(new ProcedureRelationshipElement(callee)); 3827 if (isBuiltInFunctionName(function) 3828 || isKeyword(function)) { 3829 callRelation.setBuiltIn(true); 3830 } 3831 } 3832 } 3833 if (callee.getArguments() != null) { 3834 for (int i = 0; i < callee.getArguments().size(); i++) { 3835 Argument argument = callee.getArguments().get(i); 3836 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 3837 if (variable != null) { 3838 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 3839 Transform transform = new Transform(); 3840 transform.setType(Transform.FUNCTION); 3841 transform.setCode(callStmt); 3842 variable.getColumns().get(0).setTransform(transform); 3843 } 3844 Process process = modelFactory.createProcess(callStmt); 3845 variable.addProcess(process); 3846 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), callStmt, i, 3847 process); 3848 } 3849 } 3850 } 3851 } 3852 } 3853 } 3854 3855 private boolean analyzeCustomFunctionCall(TFunctionCall functionCall) { 3856 Procedure callee = modelManager.getProcedureByName( 3857 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3858 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 3859 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3860 callee = modelManager.getProcedureByName( 3861 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3862 } 3863 if (callee != null) { 3864 String procedureParent = getProcedureParentName(stmtStack.peek()); 3865 if (procedureParent != null) { 3866 Procedure caller = modelManager 3867 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3868 if (caller != null) { 3869 CallRelationship callRelation = modelFactory.createCallRelation(); 3870 callRelation.setCallObject(functionCall); 3871 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3872 callRelation.addSource(new ProcedureRelationshipElement(callee)); 3873 if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){ 3874 callRelation.setBuiltIn(true); 3875 } 3876 } 3877 } 3878 if (callee.getArguments() != null) { 3879 for (int i = 0; i < callee.getArguments().size(); i++) { 3880 Argument argument = callee.getArguments().get(i); 3881 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 3882 if(variable!=null) { 3883 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 3884 Transform transform = new Transform(); 3885 transform.setType(Transform.FUNCTION); 3886 transform.setCode(functionCall); 3887 variable.getColumns().get(0).setTransform(transform); 3888 } 3889 Process process = modelFactory.createProcess(functionCall); 3890 variable.addProcess(process); 3891 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process); 3892 } 3893 } 3894 } 3895 return true; 3896 } 3897 return false; 3898 } 3899 3900 private void analyzeOracleBasicStmt(TBasicStmt oracleBasicStmt) { 3901 if (oracleBasicStmt.getExpr() == null || oracleBasicStmt.getExpr().getFunctionCall() == null) { 3902 return; 3903 } 3904 3905 TFunctionCall functionCall = oracleBasicStmt.getExpr().getFunctionCall(); 3906 Procedure callee = modelManager.getProcedureByName( 3907 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3908 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 3909 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3910 callee = modelManager.getProcedureByName( 3911 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3912 } 3913 if (callee != null) { 3914 String procedureParent = getProcedureParentName(oracleBasicStmt); 3915 if (procedureParent != null) { 3916 Procedure caller = modelManager 3917 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3918 if (caller != null) { 3919 CallRelationship callRelation = modelFactory.createCallRelation(); 3920 callRelation.setCallObject(functionCall); 3921 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3922 callRelation.addSource(new ProcedureRelationshipElement(callee)); 3923 if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString()) 3924 || (isBuiltInFunctionName(functionCall.getFunctionName()) 3925 || isKeyword(functionCall.getFunctionName()))) { 3926 callRelation.setBuiltIn(true); 3927 } 3928 } 3929 } 3930 if (callee.getArguments() != null) { 3931 for (int i = 0; i < callee.getArguments().size(); i++) { 3932 Argument argument = callee.getArguments().get(i); 3933 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 3934 if(variable!=null) { 3935 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 3936 Transform transform = new Transform(); 3937 transform.setType(Transform.FUNCTION); 3938 transform.setCode(functionCall); 3939 variable.getColumns().get(0).setTransform(transform); 3940 } 3941 Process process = modelFactory.createProcess(functionCall); 3942 variable.addProcess(process); 3943 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process); 3944 } 3945 } 3946 } 3947 } else { 3948 Function function = modelFactory.createFunction(functionCall); 3949 String procedureParent = getProcedureParentName(oracleBasicStmt); 3950 if (procedureParent != null) { 3951 Procedure caller = modelManager 3952 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3953 if (caller != null) { 3954 CallRelationship callRelation = modelFactory.createCallRelation(); 3955 callRelation.setCallObject(functionCall); 3956 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3957 callRelation.addSource(new FunctionRelationshipElement(function)); 3958 if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString()) 3959 || (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName()))) { 3960 callRelation.setBuiltIn(true); 3961 } 3962 } 3963 } 3964 } 3965 } 3966 3967 private void analyzeIfStmt(TIfStmt ifStmt) { 3968 if (ifStmt.getCondition() != null) { 3969 columnsInExpr visitor = new columnsInExpr(); 3970 ifStmt.getCondition().inOrderTraverse(visitor); 3971 List<TParseTreeNode> functions = visitor.getFunctions(); 3972 3973 if (functions != null && !functions.isEmpty()) { 3974 for (int i = 0; i < functions.size(); i++) { 3975 if (!(functions.get(i) instanceof TFunctionCall)) 3976 continue; 3977 TFunctionCall functionCall = (TFunctionCall) functions.get(i); 3978 Procedure callee = modelManager.getProcedureByName(DlineageUtil 3979 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3980 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 3981 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3982 callee = modelManager.getProcedureByName( 3983 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3984 } 3985 if (callee != null) { 3986 String procedureParent = getProcedureParentName(ifStmt); 3987 if (procedureParent != null) { 3988 Procedure caller = modelManager 3989 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3990 if (caller != null) { 3991 CallRelationship callRelation = modelFactory.createCallRelation(); 3992 callRelation.setCallObject(functionCall); 3993 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3994 callRelation.addSource(new ProcedureRelationshipElement(callee)); 3995 if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) { 3996 callRelation.setBuiltIn(true); 3997 } 3998 } 3999 } 4000 if (callee.getArguments() != null) { 4001 for (int j = 0; j < callee.getArguments().size(); j++) { 4002 Argument argument = callee.getArguments().get(j); 4003 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4004 if(variable!=null) { 4005 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4006 Transform transform = new Transform(); 4007 transform.setType(Transform.FUNCTION); 4008 transform.setCode(functionCall); 4009 variable.getColumns().get(0).setTransform(transform); 4010 } 4011 Process process = modelFactory.createProcess(functionCall); 4012 variable.addProcess(process); 4013 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process); 4014 } 4015 } 4016 } 4017 } else { 4018 Function function = modelFactory.createFunction(functionCall); 4019 String procedureParent = getProcedureParentName(ifStmt); 4020 if (procedureParent != null) { 4021 Procedure caller = modelManager 4022 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4023 if (caller != null) { 4024 CallRelationship callRelation = modelFactory.createCallRelation(); 4025 callRelation.setCallObject(functionCall); 4026 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4027 callRelation.addSource(new FunctionRelationshipElement(function)); 4028 if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) { 4029 callRelation.setBuiltIn(true); 4030 } 4031 } 4032 } 4033 } 4034 } 4035 } 4036 } 4037 4038 if (ifStmt.getThenStatements() != null) { 4039 for (int i = 0; i < ifStmt.getThenStatements().size(); ++i) { 4040 analyzeCustomSqlStmt(ifStmt.getThenStatements().get(i)); 4041 ResultSet returnResult = modelFactory.createResultSet(ifStmt.getThenStatements().get(i), false); 4042 if(returnResult!=null){ 4043 for(ResultColumn resultColumn: returnResult.getColumns()){ 4044 analyzeFilterCondition(resultColumn, ifStmt.getCondition(), null, null, EffectType.function); 4045 } 4046 } 4047 } 4048 } 4049 4050 if (ifStmt.getElseifStatements() != null) { 4051 for (int i = 0; i < ifStmt.getElseifStatements().size(); ++i) { 4052 analyzeCustomSqlStmt(ifStmt.getElseifStatements().get(i)); 4053 } 4054 } 4055 4056 if (ifStmt.getElseStatements() != null) { 4057 for (int i = 0; i < ifStmt.getElseStatements().size(); ++i) { 4058 analyzeCustomSqlStmt(ifStmt.getElseStatements().get(i)); 4059 } 4060 } 4061 } 4062 4063 private void analyzeElsIfStmt(TElsifStmt elsIfStmt) { 4064 if (elsIfStmt.getCondition() != null) { 4065 columnsInExpr visitor = new columnsInExpr(); 4066 elsIfStmt.getCondition().inOrderTraverse(visitor); 4067 List<TParseTreeNode> functions = visitor.getFunctions(); 4068 4069 if (functions != null && !functions.isEmpty()) { 4070 for (int i = 0; i < functions.size(); i++) { 4071 if (!(functions.get(i) instanceof TFunctionCall)) 4072 continue; 4073 TFunctionCall functionCall = (TFunctionCall) functions.get(i); 4074 Procedure callee = modelManager.getProcedureByName(DlineageUtil 4075 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4076 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 4077 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4078 callee = modelManager.getProcedureByName( 4079 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4080 } 4081 if (callee != null) { 4082 String procedureParent = getProcedureParentName(elsIfStmt); 4083 if (procedureParent != null) { 4084 Procedure caller = modelManager 4085 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4086 if (caller != null) { 4087 CallRelationship callRelation = modelFactory.createCallRelation(); 4088 callRelation.setCallObject(functionCall); 4089 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4090 callRelation.addSource(new ProcedureRelationshipElement(callee)); 4091 if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){ 4092 callRelation.setBuiltIn(true); 4093 } 4094 } 4095 } 4096 if (callee.getArguments() != null) { 4097 for (int j = 0; j < callee.getArguments().size(); j++) { 4098 Argument argument = callee.getArguments().get(j); 4099 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4100 if(variable!=null) { 4101 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4102 Transform transform = new Transform(); 4103 transform.setType(Transform.FUNCTION); 4104 transform.setCode(functionCall); 4105 variable.getColumns().get(0).setTransform(transform); 4106 } 4107 Process process = modelFactory.createProcess(functionCall); 4108 variable.addProcess(process); 4109 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process); 4110 } 4111 } 4112 } 4113 } else { 4114 Function function = modelFactory.createFunction(functionCall); 4115 String procedureParent = getProcedureParentName(elsIfStmt); 4116 if (procedureParent != null) { 4117 Procedure caller = modelManager 4118 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4119 if (caller != null) { 4120 CallRelationship callRelation = modelFactory.createCallRelation(); 4121 callRelation.setCallObject(functionCall); 4122 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4123 callRelation.addSource(new FunctionRelationshipElement(function)); 4124 if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){ 4125 callRelation.setBuiltIn(true); 4126 } 4127 } 4128 } 4129 } 4130 } 4131 } 4132 } 4133 4134 if (elsIfStmt.getThenStatements() != null) { 4135 for (int i = 0; i < elsIfStmt.getThenStatements().size(); ++i) { 4136 ResultSet returnResult = modelFactory.createResultSet(elsIfStmt.getThenStatements().get(i), false); 4137 if (returnResult != null) { 4138 for (ResultColumn resultColumn : returnResult.getColumns()) { 4139 analyzeFilterCondition(resultColumn, elsIfStmt.getCondition(), null, null, EffectType.function); 4140 } 4141 } 4142 analyzeCustomSqlStmt(elsIfStmt.getThenStatements().get(i)); 4143 } 4144 } 4145 } 4146 4147 private void analyzeCloneTableStmt(TCreateTableSqlStatement stmt) { 4148 if (stmt.getCloneSourceTable() != null) { 4149 Table sourceTable = modelFactory.createTableByName(stmt.getCloneSourceTable()); 4150 Table cloneTable = modelFactory.createTableByName(stmt.getTableName()); 4151 Process process = modelFactory.createProcess(stmt); 4152 cloneTable.addProcess(process); 4153 4154 if (sourceTable.isDetermined()) { 4155 for (int k = 0; k < sourceTable.getColumns().size(); k++) { 4156 TableColumn sourceColumn = sourceTable.getColumns().get(k); 4157 TObjectName objectName = new TObjectName(); 4158 objectName.setString(sourceColumn.getName()); 4159 TableColumn tableColumn = modelFactory.createTableColumn(cloneTable, objectName, true); 4160 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4161 dataflowRelation.setEffectType(EffectType.clone_table); 4162 dataflowRelation 4163 .addSource(new TableColumnRelationshipElement(sourceColumn)); 4164 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 4165 dataflowRelation.setProcess(process); 4166 } 4167 cloneTable.setDetermined(true); 4168 cloneTable.setFromDDL(true); 4169 } else { 4170 TObjectName sourceName = new TObjectName(); 4171 sourceName.setString("*"); 4172 TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceName, false); 4173 TObjectName targetName = new TObjectName(); 4174 targetName.setString("*"); 4175 TableColumn targetTableColumn = modelFactory.createTableColumn(cloneTable, targetName, false); 4176 if(sourceTableColumn!=null && targetTableColumn!=null) { 4177 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4178 dataflowRelation.setEffectType(EffectType.clone_table); 4179 dataflowRelation 4180 .addSource(new TableColumnRelationshipElement(sourceTableColumn)); 4181 dataflowRelation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 4182 dataflowRelation.setProcess(process); 4183 } 4184 } 4185 } 4186 } 4187 4188 private void analyzeCloneDatabaseStmt(TCreateDatabaseSqlStatement stmt) { 4189 if (stmt.getCloneSourceDb() != null) { 4190 Database sourceDatabase = modelFactory.createDatabase(stmt.getCloneSourceDb()); 4191 Database cloneDatabase = modelFactory.createDatabase(stmt.getDatabaseName()); 4192 Process process = modelFactory.createProcess(stmt); 4193 cloneDatabase.addProcess(process); 4194 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4195 relation.setEffectType(EffectType.clone_database); 4196 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneDatabase.getRelationRows())); 4197 relation.addSource( 4198 new RelationRowsRelationshipElement<TableRelationRows>(sourceDatabase.getRelationRows())); 4199 relation.setProcess(process); 4200 } 4201 } 4202 4203 private void analyzeCloneSchemaStmt(TCreateSchemaSqlStatement stmt) { 4204 if (stmt.getCloneSourceSchema() != null) { 4205 Schema sourceSchema = modelFactory.createSchema(stmt.getCloneSourceSchema()); 4206 Schema cloneSchema = modelFactory.createSchema(stmt.getSchemaName()); 4207 Process process = modelFactory.createProcess(stmt); 4208 cloneSchema.addProcess(process); 4209 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4210 relation.setEffectType(EffectType.clone_schema); 4211 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneSchema.getRelationRows())); 4212 relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(sourceSchema.getRelationRows())); 4213 relation.setProcess(process); 4214 } 4215 } 4216 4217 private void executeDynamicSql(String sql) { 4218 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 4219 sqlparser.sqltext = sql; 4220 int result = sqlparser.parse(); 4221 if (result == 0) { 4222 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 4223 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 4224 } 4225 } 4226 } 4227 4228 private void extractSnowflakeSQLFromProcedure(TCreateProcedureStmt procedure) { 4229 Map<String, String> argMap = new LinkedHashMap<String, String>(); 4230 if (procedure.getParameterDeclarations() != null) { 4231 for (int i = 0; i < procedure.getParameterDeclarations().size(); i++) { 4232 TParameterDeclaration def = procedure.getParameterDeclarations().getParameterDeclarationItem(i); 4233 argMap.put(def.getParameterName().toString(), def.getDataType().getDataTypeName()); 4234 } 4235 } 4236 StringBuilder buffer = new StringBuilder(); 4237 buffer.append("(function("); 4238 String[] args = argMap.keySet().toArray(new String[0]); 4239 for (int i = 0; i < args.length; i++) { 4240 buffer.append(args[i].toUpperCase()); 4241 if (i < args.length - 1) { 4242 buffer.append(","); 4243 } 4244 } 4245 buffer.append("){\n"); 4246 4247 int start = -1; 4248 int end = -1; 4249 boolean dollar = false; 4250 boolean quote = false; 4251 if (procedure.getRoutineBody().indexOf("$$") != -1) { 4252 start = procedure.getRoutineBody().indexOf("$$") + 2; 4253 end = procedure.getRoutineBody().lastIndexOf("$$") - 1; 4254 dollar = true; 4255 } else if (procedure.getRoutineBody().indexOf("'") != -1) { 4256 start = procedure.getRoutineBody().indexOf("'") + 1; 4257 end = procedure.getRoutineBody().lastIndexOf("'"); 4258 quote = true; 4259 } 4260 String body = procedure.getRoutineBody().substring(start, end); 4261 if (dollar && body.indexOf("`") != -1) { 4262 Pattern pattern = Pattern.compile("`.+?`", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); 4263 Matcher matcher = pattern.matcher(body); 4264 StringBuffer replaceBuffer = new StringBuffer(); 4265 while (matcher.find()) { 4266 String condition = matcher.group().replace("\r\n", "\n").replace("'", "\\\\'") 4267 .replace("\n", "\\\\n'\n+'").replace("`", "'").replace("$", "RDS_CHAR_DOLLAR"); 4268 matcher.appendReplacement(replaceBuffer, condition); 4269 } 4270 matcher.appendTail(replaceBuffer); 4271 body = replaceBuffer.toString().replace("RDS_CHAR_DOLLAR", "$"); 4272 } 4273 if (quote && body.indexOf("'") != -1) { 4274 body = body.replace("''", "'"); 4275 } 4276 buffer.append(body); 4277 buffer.append("})("); 4278 for (int i = 0; i < args.length; i++) { 4279 String type = argMap.get(args[i]); 4280 if (type.equalsIgnoreCase("VARCHAR")) { 4281 buffer.append("'pseudo'"); 4282 } else if (type.equalsIgnoreCase("STRING")) { 4283 buffer.append("'pseudo'"); 4284 } else if (type.equalsIgnoreCase("CHAR")) { 4285 buffer.append("'pseudo'"); 4286 } else if (type.equalsIgnoreCase("CHARACTER")) { 4287 buffer.append("'pseudo'"); 4288 } else if (type.equalsIgnoreCase("TEXT")) { 4289 buffer.append("'pseudo'"); 4290 } else if (type.equalsIgnoreCase("BINARY")) { 4291 buffer.append("'pseudo'"); 4292 } else if (type.equalsIgnoreCase("VARBINARY")) { 4293 buffer.append("'pseudo'"); 4294 } else if (type.equalsIgnoreCase("BOOLEAN")) { 4295 buffer.append(true); 4296 } else if (type.equalsIgnoreCase("FLOAT")) { 4297 buffer.append("1.0"); 4298 } else if (type.equalsIgnoreCase("FLOAT4")) { 4299 buffer.append("1.0"); 4300 } else if (type.equalsIgnoreCase("FLOAT8")) { 4301 buffer.append("1.0"); 4302 } else if (type.equalsIgnoreCase("DOUBLE")) { 4303 buffer.append("1.0"); 4304 } else if (type.equalsIgnoreCase("DOUBLE PRECISION")) { 4305 buffer.append("1.0"); 4306 } else if (type.equalsIgnoreCase("REAL")) { 4307 buffer.append("1.0"); 4308 } else if (type.equalsIgnoreCase("NUMBER")) { 4309 buffer.append("1.0"); 4310 } else if (type.equalsIgnoreCase("DECIMAL")) { 4311 buffer.append("1.0"); 4312 } else if (type.equalsIgnoreCase("NUMERIC")) { 4313 buffer.append("1.0"); 4314 } else if (type.equalsIgnoreCase("INT")) { 4315 buffer.append("1"); 4316 } else if (type.equalsIgnoreCase("INTEGER")) { 4317 buffer.append("1"); 4318 } else if (type.equalsIgnoreCase("BIGINT")) { 4319 buffer.append("1"); 4320 } else if (type.equalsIgnoreCase("SMALLINT")) { 4321 buffer.append("1"); 4322 } else if (type.equalsIgnoreCase("DATE")) { 4323 buffer.append("new Date()"); 4324 } else if (type.equalsIgnoreCase("DATETIME")) { 4325 buffer.append("new Date()"); 4326 } else if (type.equalsIgnoreCase("TIME")) { 4327 buffer.append("new Date()"); 4328 } else if (type.equalsIgnoreCase("TIMESTAMP")) { 4329 buffer.append("new Date()"); 4330 } else if (type.equalsIgnoreCase("TIMESTAMP_LTZ")) { 4331 buffer.append("new Date()"); 4332 } else if (type.equalsIgnoreCase("TIMESTAMP_NTZ")) { 4333 buffer.append("new Date()"); 4334 } else if (type.equalsIgnoreCase("TIMESTAMP_TZ")) { 4335 buffer.append("new Date()"); 4336 } else if (type.equalsIgnoreCase("VARIANT")) { 4337 buffer.append("{}"); 4338 } else if (type.equalsIgnoreCase("OBJECT")) { 4339 buffer.append("{}"); 4340 } else if (type.equalsIgnoreCase("ARRAY")) { 4341 buffer.append("[]"); 4342 } else if (type.equalsIgnoreCase("GEOGRAPHY")) { 4343 buffer.append("{}"); 4344 } 4345 if (i < args.length - 1) { 4346 buffer.append(","); 4347 } 4348 } 4349 buffer.append(");"); 4350 4351 try { 4352 ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); 4353 ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn"); 4354 nashorn.put("analyzer", this); 4355 nashorn.eval(new InputStreamReader( 4356 getClass().getResourceAsStream("/gudusoft/gsqlparser/parser/snowflake/snowflake.js"))); 4357 nashorn.eval(new StringReader(buffer.toString())); 4358 } catch (ScriptException e) { 4359 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 4360 sqlparser.sqltext = body; 4361 int result = sqlparser.parse(); 4362 if (result == 0) { 4363 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 4364 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 4365 } 4366 return; 4367 } 4368 ErrorInfo errorInfo = new ErrorInfo(); 4369 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 4370 errorInfo.setErrorMessage("Invoke script error: " + e.getMessage()); 4371 errorInfo.setStartPosition(new Pair3<Long, Long, String>(procedure.getStartToken().lineNo, 4372 procedure.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 4373 errorInfo.setEndPosition(new Pair3<Long, Long, String>(procedure.getEndToken().lineNo, 4374 procedure.getEndToken().columnNo + procedure.getEndToken().getAstext().length(), 4375 ModelBindingManager.getGlobalHash())); 4376 errorInfos.add(errorInfo); 4377 } 4378 } 4379 4380 private void analyzeHiveLoadStmt(THiveLoad stmt) { 4381 if (stmt.getPath() != null && stmt.getTable() != null) { 4382 Table uriFile = modelFactory.createTableByName(stmt.getPath(), true); 4383 uriFile.setPath(true); 4384 uriFile.setCreateTable(true); 4385 TObjectName fileUri = new TObjectName(); 4386 fileUri.setString("uri=" + stmt.getPath()); 4387 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 4388 4389 Table tableModel = modelFactory.createTable(stmt.getTable()); 4390 Process process = modelFactory.createProcess(stmt); 4391 tableModel.addProcess(process); 4392 4393 TPartitionExtensionClause p = stmt.getTable().getPartitionExtensionClause(); 4394 if (p.getKeyValues() != null && p.getKeyValues().size() > 0) { 4395 for (int i = 0; i < p.getKeyValues().size(); i++) { 4396 TExpression expression = p.getKeyValues().getExpression(i); 4397 if (expression.getLeftOperand().getExpressionType() == EExpressionType.simple_object_name_t) { 4398 modelFactory.createTableColumn(tableModel, expression.getLeftOperand().getObjectOperand(), 4399 true); 4400 } 4401 } 4402 } 4403 4404 for (int j = 0; j < tableModel.getColumns().size(); j++) { 4405 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4406 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 4407 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j))); 4408 relation.setProcess(process); 4409 } 4410 } 4411 } 4412 4413 private void analyzeLoadDataStmt(TLoadDataStmt stmt) { 4414 4415 } 4416 4417 private void analyzeUnloadStmt(TUnloadStmt unloadStmt) { 4418 if (unloadStmt.getSelectSqlStatement() != null && unloadStmt.getS3() != null) { 4419 4420 Table uriFile = modelFactory.createTableByName(unloadStmt.getS3(), true); 4421 uriFile.setPath(true); 4422 uriFile.setCreateTable(true); 4423 TObjectName fileUri = new TObjectName(); 4424 fileUri.setString("uri=" + unloadStmt.getS3()); 4425 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 4426 4427 Process process = modelFactory.createProcess(unloadStmt); 4428 uriFile.addProcess(process); 4429 4430 TCustomSqlStatement stmt = unloadStmt.getSelectSqlStatement(); 4431 analyzeCustomSqlStmt(stmt); 4432 if (stmt instanceof TSelectSqlStatement) { 4433 TSelectSqlStatement select = (TSelectSqlStatement) stmt; 4434 ResultSet resultSetModel = (ResultSet) modelManager.getModel(select); 4435 if (resultSetModel != null) { 4436 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 4437 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 4438 if (resultColumn.hasStarLinkColumn() 4439 && resultColumn.getStarLinkColumnNames().size() > 0) { 4440 for (int k = 0; k < resultColumn.getStarLinkColumnNames().size(); k++) { 4441 ResultColumn expandStarColumn = modelFactory.createResultColumn(resultSetModel, 4442 resultColumn.getStarLinkColumnName(k), false); 4443 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4444 dataflowRelation.setEffectType(EffectType.unload); 4445 dataflowRelation 4446 .addSource(new ResultColumnRelationshipElement(expandStarColumn)); 4447 dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn)); 4448 dataflowRelation.setProcess(process); 4449 } 4450 } 4451 if (!resultColumn.hasStarLinkColumn() || resultColumn.isShowStar()) { 4452 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4453 dataflowRelation.setEffectType(EffectType.unload); 4454 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 4455 dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn)); 4456 dataflowRelation.setProcess(process); 4457 } 4458 } 4459 } 4460 } 4461 } 4462 4463 } 4464 4465 private void analyzeCopyIntoStmt(TSnowflakeCopyIntoStmt stmt) { 4466 if (stmt.getTableName() != null) { 4467 if (stmt.getStageLocation() != null) { 4468 Table intoTable = modelManager 4469 .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString())); 4470 if (intoTable == null) { 4471 intoTable = modelFactory.createTableByName(stmt.getTableName(), false); 4472 TObjectName starColumn = new TObjectName(); 4473 starColumn.setString("*"); 4474 TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false); 4475 if (column != null) { 4476 column.setExpandStar(false); 4477 column.setPseduo(true); 4478 } 4479 } 4480 Process process = modelFactory.createProcess(stmt); 4481 intoTable.addProcess(process); 4482 4483 TObjectName stageName = stmt.getStageLocation().getStageName(); 4484 if (stageName == null || stmt.getStageLocation().getTableName() != null) { 4485 stageName = stmt.getStageLocation().getTableName(); 4486 } 4487 if (stageName != null) { 4488 String stageFullName = DlineageUtil.getTableFullName(stageName.toString()); 4489 Table stage = modelManager.getTableByName(stageFullName); 4490 if (stage == null) { 4491 stage = modelFactory.createStage(stageName); 4492 stage.setCreateTable(true); 4493 stage.setStage(true); 4494 String stagePath = stmt.getStageLocation().getPath() == null ? null 4495 : stmt.getStageLocation().getPath().toString(); 4496 if (stagePath != null) { 4497 stage.setLocation(stagePath); 4498 TObjectName location = new TObjectName(); 4499 location.setString(stagePath); 4500 modelFactory.createStageLocation(stage, location); 4501 } else { 4502 stage.setLocation("unknownPath"); 4503 TObjectName location = new TObjectName(); 4504 location.setString("unknownPath"); 4505 modelFactory.createStageLocation(stage, location); 4506 } 4507 } 4508 4509 if (stage != null && intoTable != null) { 4510 if (intoTable != null && !intoTable.getColumns().isEmpty() && !stage.getColumns().isEmpty()) { 4511 for (int i = 0; i < intoTable.getColumns().size(); i++) { 4512 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4513 relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0))); 4514 relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i))); 4515 relation.setProcess(process); 4516 } 4517 } 4518 } 4519 } else if (stmt.getStageLocation().getExternalLocation() != null) { 4520 Table pathModel = modelFactory.createTableByName(stmt.getStageLocation().getExternalLocation(), 4521 true); 4522 pathModel.setPath(true); 4523 pathModel.setCreateTable(true); 4524 TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, 4525 stmt.getStageLocation().getExternalLocation()); 4526 if (intoTable != null) { 4527 if (intoTable != null && !intoTable.getColumns().isEmpty()) { 4528 for (int i = 0; i < intoTable.getColumns().size(); i++) { 4529 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4530 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 4531 relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i))); 4532 relation.setProcess(process); 4533 } 4534 } 4535 } 4536 } 4537 } 4538 else if (stmt.getSubQuery() != null) { 4539 analyzeSelectStmt(stmt.getSubQuery()); 4540 4541 Table intoTable = modelManager 4542 .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString())); 4543 if (intoTable == null) { 4544 intoTable = modelFactory.createTableByName(stmt.getTableName(), false); 4545 TObjectName starColumn = new TObjectName(); 4546 starColumn.setString("*"); 4547 TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false); 4548 if (column != null) { 4549 column.setExpandStar(true); 4550 column.setPseduo(true); 4551 } 4552 4553 Process process = modelFactory.createProcess(stmt); 4554 intoTable.addProcess(process); 4555 4556 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 4557 if (resultSetModel != null && column != null) { 4558 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 4559 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 4560 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4561 dataflowRelation.setEffectType(EffectType.copy); 4562 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 4563 dataflowRelation.setTarget(new TableColumnRelationshipElement(column)); 4564 dataflowRelation.setProcess(process); 4565 } 4566 } 4567 } 4568 } 4569 } 4570 } 4571 4572 private void analyzeRedshiftCopyStmt(TRedshiftCopy stmt) { 4573 if (stmt.getTableName() != null && stmt.getFromSource() != null) { 4574 4575 Table intoTable = modelManager 4576 .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString())); 4577 if (intoTable == null) { 4578 intoTable = modelFactory.createTableByName(stmt.getTableName(), false); 4579 if (stmt.getColumnList() == null || stmt.getColumnList().size() == 0) { 4580 TObjectName starColumn = new TObjectName(); 4581 starColumn.setString("*"); 4582 TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false); 4583 if (column != null) { 4584 column.setExpandStar(false); 4585 column.setPseduo(true); 4586 } 4587 } else { 4588 for (TObjectName columnName : stmt.getColumnList()) { 4589 modelFactory.createTableColumn(intoTable, columnName, true); 4590 } 4591 } 4592 } 4593 Process process = modelFactory.createProcess(stmt); 4594 intoTable.addProcess(process); 4595 4596 if (stmt.getFromSource() != null) { 4597 Table pathModel = modelFactory.createTableByName(stmt.getFromSource(), true); 4598 pathModel.setPath(true); 4599 pathModel.setCreateTable(true); 4600 TObjectName fileUri = new TObjectName(); 4601 fileUri.setString(stmt.getFromSource()); 4602 TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri); 4603 if (intoTable != null) { 4604 if (intoTable != null && !intoTable.getColumns().isEmpty()) { 4605 for (int i = 0; i < intoTable.getColumns().size(); i++) { 4606 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4607 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 4608 relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i))); 4609 relation.setProcess(process); 4610 } 4611 } 4612 } 4613 } 4614 } 4615 } 4616 4617 private void analyzeCreateIndexExpressionOperand(TExpression expr, Table tableModel){ 4618 if(expr == null) return; 4619 Deque<TExpression> stack = new ArrayDeque<>(); 4620 stack.push(expr); 4621 while (!stack.isEmpty()) { 4622 TExpression current = stack.pop(); 4623 if (current == null) continue; 4624 TObjectName columnObj = current.getObjectOperand(); 4625 if (columnObj != null) { 4626 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, columnObj, true); 4627 tableConstraint.setIndexKey(true); 4628 } else { 4629 if (current.getRightOperand() != null) { 4630 stack.push(current.getRightOperand()); 4631 } 4632 if (current.getLeftOperand() != null) { 4633 stack.push(current.getLeftOperand()); 4634 } 4635 } 4636 } 4637 } 4638 private void analyzeCreateIndexStageStmt(TCreateIndexSqlStatement stmt) { 4639 if(stmt.getTableName() == null){ 4640 return; 4641 } 4642 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 4643 TOrderByItemList columns = stmt.getColumnNameList(); 4644 if(columns!=null) { 4645 for (int i = 0; i < columns.size(); i++) { 4646 TExpression expr = columns.getOrderByItem(i).getSortKey(); 4647 analyzeCreateIndexExpressionOperand(expr, tableModel); 4648 } 4649 } 4650 } 4651 4652 private void analyzeCreateSynonymStmt(TCreateSynonymStmt stmt) { 4653 TObjectName sourceTableName = stmt.getForName(); 4654 if(sourceTableName == null) { 4655 return; 4656 } 4657 TCustomSqlStatement createView = viewDDLMap 4658 .get(DlineageUtil.getTableFullName(sourceTableName.toString())); 4659 if (createView != null) { 4660 analyzeCustomSqlStmt(createView); 4661 } 4662 Table sourceTableModel = modelFactory.createTableByName(sourceTableName); 4663 Process process = modelFactory.createProcess(stmt); 4664 sourceTableModel.addProcess(process); 4665 if(stmt.getSynonymName()!=null) { 4666 Table synonymTableModel = modelFactory.createTableByName(stmt.getSynonymName()); 4667 synonymTableModel.setSubType(SubType.synonym); 4668 if(sourceTableModel.isCreateTable()) { 4669 synonymTableModel.setCreateTable(true); 4670 for(TableColumn sourceTableColumn: sourceTableModel.getColumns()) { 4671 TObjectName columnName = new TObjectName(); 4672 columnName.setString(sourceTableColumn.getName()); 4673 TableColumn synonymTableColumn = new TableColumn(synonymTableModel, columnName); 4674 synonymTableModel.addColumn(synonymTableColumn); 4675 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4676 relation.setEffectType(EffectType.create_synonym); 4677 relation.setTarget(new TableColumnRelationshipElement(synonymTableColumn)); 4678 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 4679 relation.setProcess(process); 4680 } 4681 } 4682 else { 4683 TObjectName synonymStarColumn = new TObjectName(); 4684 synonymStarColumn.setString("*"); 4685 TableColumn synonymTableStarColumn = modelFactory.createTableColumn(synonymTableModel, 4686 synonymStarColumn, true); 4687 TObjectName sourceStarColumn = new TObjectName(); 4688 sourceStarColumn.setString("*"); 4689 TableColumn sourceTableStarColumn = modelFactory.createTableColumn(sourceTableModel, sourceStarColumn, true); 4690 4691 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4692 relation.setEffectType(EffectType.create_synonym); 4693 relation.setTarget(new TableColumnRelationshipElement(synonymTableStarColumn)); 4694 relation.addSource(new TableColumnRelationshipElement(sourceTableStarColumn)); 4695 relation.setProcess(process); 4696 } 4697 } 4698 } 4699 4700 private void analyzeRenameStmt(TRenameStmt stmt) { 4701 TObjectName oldTableName = stmt.getOldName(); 4702 TObjectName newTableName = stmt.getNewName(); 4703 4704 Table oldNameTableModel = modelFactory.createTableByName(oldTableName); 4705 TObjectName oldStarColumn = new TObjectName(); 4706 oldStarColumn.setString("*"); 4707 TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true); 4708 4709 Table newNameTableModel = modelFactory.createTableByName(newTableName); 4710 TObjectName newStarColumn = new TObjectName(); 4711 newStarColumn.setString("*"); 4712 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true); 4713 4714 Process process = modelFactory.createProcess(stmt); 4715 newNameTableModel.addProcess(process); 4716 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4717 relation.setEffectType( EffectType.rename_table); 4718 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 4719 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 4720 relation.setProcess(process); 4721 4722 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4723 oldTableStarColumn.setShowStar(false); 4724 relation.setShowStarRelation(false); 4725 } 4726 4727 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4728 newTableStarColumn.setShowStar(false); 4729 relation.setShowStarRelation(false); 4730 } 4731 } 4732 4733 private void analyzeAlterTableStmt(TAlterTableStatement stmt) { 4734 TTable oldNameTable = stmt.getTargetTable(); 4735 if (oldNameTable == null) { 4736 return; 4737 } 4738 4739 Table oldNameTableModel = modelFactory.createTable(oldNameTable); 4740 TObjectName oldStarColumn = new TObjectName(); 4741 oldStarColumn.setString("*"); 4742 TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true); 4743 4744 for (int i = 0; stmt.getAlterTableOptionList() != null && i < stmt.getAlterTableOptionList().size(); i++) { 4745 TAlterTableOption option = stmt.getAlterTableOptionList().getAlterTableOption(i); 4746 if (option.getOptionType() == EAlterTableOptionType.RenameTable 4747 || option.getOptionType() == EAlterTableOptionType.swapWith) { 4748 TObjectName newTableName = option.getNewTableName(); 4749 Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken(); 4750 boolean containsTable = false; 4751 for (int j = 0; j < list.size(); j++) { 4752 if (list.get(j) instanceof TTable) { 4753 TTable newTableTable = (TTable) list.get(j); 4754 Table newNameTableModel = modelFactory.createTable(newTableTable); 4755 newNameTableModel.setStarStmt("rename_table"); 4756 4757 TObjectName newStarColumn = new TObjectName(); 4758 newStarColumn.setString("*"); 4759 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, 4760 newStarColumn, true); 4761 4762 Process process = modelFactory.createProcess(stmt); 4763 newNameTableModel.addProcess(process); 4764 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4765 relation.setEffectType( 4766 option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table 4767 : EffectType.swap_table); 4768 if (option.getOptionType() == EAlterTableOptionType.RenameTable) { 4769 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 4770 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 4771 } else if (option.getOptionType() == EAlterTableOptionType.swapWith) { 4772 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 4773 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 4774 } 4775 relation.setProcess(process); 4776 containsTable = true; 4777 4778 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4779 oldTableStarColumn.setShowStar(false); 4780 relation.setShowStarRelation(false); 4781 } 4782 4783 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4784 newTableStarColumn.setShowStar(false); 4785 relation.setShowStarRelation(false); 4786 } 4787 } 4788 } 4789 if (!containsTable) { 4790 Table newNameTableModel = modelFactory.createTableByName(newTableName); 4791 newNameTableModel.setStarStmt("rename_table"); 4792 TObjectName newStarColumn = new TObjectName(); 4793 newStarColumn.setString("*"); 4794 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, 4795 true); 4796 4797 Process process = modelFactory.createProcess(stmt); 4798 newNameTableModel.addProcess(process); 4799 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4800 relation.setEffectType( 4801 option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table 4802 : EffectType.swap_table); 4803 if (option.getOptionType() == EAlterTableOptionType.RenameTable) { 4804 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 4805 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 4806 } else if (option.getOptionType() == EAlterTableOptionType.swapWith) { 4807 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 4808 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 4809 } 4810 relation.setProcess(process); 4811 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4812 oldTableStarColumn.setShowStar(false); 4813 relation.setShowStarRelation(false); 4814 } 4815 4816 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4817 newTableStarColumn.setShowStar(false); 4818 relation.setShowStarRelation(false); 4819 } 4820 4821 } 4822 } 4823 else if (option.getOptionType() == EAlterTableOptionType.appendFrom) { 4824 TObjectName newTableName = option.getSourceTableName(); 4825 Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken(); 4826 boolean containsTable = false; 4827 for (int j = 0; j < list.size(); j++) { 4828 if (list.get(j) instanceof TTable) { 4829 TTable newTableTable = (TTable) list.get(j); 4830 Table newNameTableModel = modelFactory.createTable(newTableTable); 4831 newNameTableModel.setStarStmt("append_from"); 4832 4833 TObjectName newStarColumn = new TObjectName(); 4834 newStarColumn.setString("*"); 4835 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, 4836 newStarColumn, true); 4837 4838 Process process = modelFactory.createProcess(stmt); 4839 newNameTableModel.addProcess(process); 4840 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4841 relation.setEffectType(EffectType.append_from); 4842 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 4843 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 4844 relation.setProcess(process); 4845 containsTable = true; 4846 4847 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4848 oldTableStarColumn.setShowStar(false); 4849 relation.setShowStarRelation(false); 4850 } 4851 4852 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4853 newTableStarColumn.setShowStar(false); 4854 relation.setShowStarRelation(false); 4855 } 4856 } 4857 } 4858 if (!containsTable) { 4859 Table newNameTableModel = modelFactory.createTableByName(newTableName); 4860 newNameTableModel.setStarStmt("append_from"); 4861 TObjectName newStarColumn = new TObjectName(); 4862 newStarColumn.setString("*"); 4863 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, 4864 true); 4865 4866 Process process = modelFactory.createProcess(stmt); 4867 newNameTableModel.addProcess(process); 4868 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4869 relation.setEffectType(EffectType.append_from); 4870 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 4871 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 4872 relation.setProcess(process); 4873 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4874 oldTableStarColumn.setShowStar(false); 4875 relation.setShowStarRelation(false); 4876 } 4877 4878 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4879 newTableStarColumn.setShowStar(false); 4880 relation.setShowStarRelation(false); 4881 } 4882 4883 } 4884 } 4885 else if (option.getOptionType() == EAlterTableOptionType.exchangePartition) { 4886 TObjectName newTableName = option.getNewTableName(); 4887 Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken(); 4888 boolean containsTable = false; 4889 for (int j = 0; j < list.size(); j++) { 4890 if (list.get(j) instanceof TTable) { 4891 TTable newTableTable = (TTable) list.get(j); 4892 Table newNameTableModel = modelFactory.createTable(newTableTable); 4893 newNameTableModel.setStarStmt("exchange_partition"); 4894 4895 TObjectName newStarColumn = new TObjectName(); 4896 newStarColumn.setString("*"); 4897 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, 4898 newStarColumn, true); 4899 4900 Process process = modelFactory.createProcess(stmt); 4901 newNameTableModel.addProcess(process); 4902 { 4903 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4904 relation.setEffectType(EffectType.exchange_partition); 4905 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 4906 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 4907 relation.setProcess(process); 4908 if (option.getPartitionName() != null) { 4909 relation.setPartition(option.getPartitionName().toString()); 4910 } 4911 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4912 oldTableStarColumn.setShowStar(false); 4913 relation.setShowStarRelation(false); 4914 } 4915 4916 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4917 newTableStarColumn.setShowStar(false); 4918 relation.setShowStarRelation(false); 4919 } 4920 } 4921 { 4922 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4923 relation.setEffectType(EffectType.exchange_partition); 4924 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 4925 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 4926 relation.setProcess(process); 4927 if (option.getPartitionName() != null) { 4928 relation.setPartition(option.getPartitionName().toString()); 4929 } 4930 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4931 oldTableStarColumn.setShowStar(false); 4932 relation.setShowStarRelation(false); 4933 } 4934 4935 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4936 newTableStarColumn.setShowStar(false); 4937 relation.setShowStarRelation(false); 4938 } 4939 } 4940 containsTable = true; 4941 } 4942 } 4943 if (!containsTable) { 4944 Table newNameTableModel = modelFactory.createTableByName(newTableName); 4945 newNameTableModel.setStarStmt("exchange_partition"); 4946 TObjectName newStarColumn = new TObjectName(); 4947 newStarColumn.setString("*"); 4948 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, 4949 true); 4950 4951 Process process = modelFactory.createProcess(stmt); 4952 newNameTableModel.addProcess(process); 4953 { 4954 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4955 relation.setEffectType(EffectType.exchange_partition); 4956 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 4957 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 4958 if (option.getPartitionName() != null) { 4959 relation.setPartition(option.getPartitionName().toString()); 4960 } 4961 relation.setProcess(process); 4962 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4963 oldTableStarColumn.setShowStar(false); 4964 relation.setShowStarRelation(false); 4965 } 4966 4967 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4968 newTableStarColumn.setShowStar(false); 4969 relation.setShowStarRelation(false); 4970 } 4971 } 4972 { 4973 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4974 relation.setEffectType(EffectType.exchange_partition); 4975 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 4976 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 4977 if (option.getPartitionName() != null) { 4978 relation.setPartition(option.getPartitionName().toString()); 4979 } 4980 relation.setProcess(process); 4981 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 4982 oldTableStarColumn.setShowStar(false); 4983 relation.setShowStarRelation(false); 4984 } 4985 4986 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 4987 newTableStarColumn.setShowStar(false); 4988 relation.setShowStarRelation(false); 4989 } 4990 } 4991 } 4992 } 4993 else if(option.getOptionType() == EAlterTableOptionType.setLocation) { 4994 TObjectName location = option.getTableLocation(); 4995 Process process = modelFactory.createProcess(stmt); 4996 process.setType("Set Table Location"); 4997 oldNameTableModel.addProcess(process); 4998 Table uriFile = modelFactory.createTableByName(location, true); 4999 uriFile.setPath(true); 5000 for (int j = 0; j < oldNameTableModel.getColumns().size(); j++) { 5001 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5002 TObjectName fileUri = new TObjectName(); 5003 fileUri.setString("*"); 5004 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 5005 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 5006 relation.setTarget(new TableColumnRelationshipElement(oldNameTableModel.getColumns().get(j))); 5007 relation.setProcess(process); 5008 } 5009 } 5010 else if (option.getOptionType() == EAlterTableOptionType.AddColumn 5011 || option.getOptionType() == EAlterTableOptionType.addColumnIfNotExists) { 5012 if (option.getColumnDefinitionList() != null) { 5013 for (TColumnDefinition column : option.getColumnDefinitionList()) { 5014 if (column != null && column.getColumnName() != null) { 5015 TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column.getColumnName(), true); 5016 if(this.option.getAnalyzeMode() == AnalyzeMode.crud) { 5017 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 5018 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 5019 crudRelationship.setEffectType(EffectType.add_table_column); 5020 } 5021 } 5022 } 5023 } 5024 } 5025 else if (option.getOptionType() == EAlterTableOptionType.DropColumn && this.option.getAnalyzeMode() == AnalyzeMode.crud) { 5026 if (option.getColumnNameList() != null) { 5027 for (TObjectName column : option.getColumnNameList()) { 5028 TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column, true); 5029 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 5030 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 5031 crudRelationship.setEffectType(EffectType.drop_table_column); 5032 } 5033 } 5034 } 5035 else if(option.getOptionType() == EAlterTableOptionType.AddConstraint || option.getOptionType() == EAlterTableOptionType.AddConstraintFK 5036 || option.getOptionType() == EAlterTableOptionType.AddConstraintPK || option.getOptionType() == EAlterTableOptionType.AddConstraintUnique 5037 || option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){ 5038 if (option.getTableConstraint() != null) { 5039 TConstraint alertTableConstraint = option.getTableConstraint(); 5040 TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList(); 5041 for (int k = 0; k < keyNames.size(); k++) { 5042 TObjectName keyName = keyNames.getElement(k).getColumnName(); 5043 TObjectName referencedTableName = alertTableConstraint.getReferencedObject(); 5044 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 5045 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 5046 if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){ 5047 tableConstraint.setPrimaryKey(true); 5048 } 5049 else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){ 5050 tableConstraint.setIndexKey(true); 5051 } 5052 else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){ 5053 tableConstraint.setUnqiueKey(true); 5054 } 5055 else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) { 5056 tableConstraint.setForeignKey(true); 5057 Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 5058 if (referencedTable == null) { 5059 referencedTable = modelFactory.createTableByName(referencedTableName); 5060 } 5061 TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList(); 5062 if (referencedTableColumns != null) { 5063 for (int j = 0; j < referencedTableColumns.size(); j++) { 5064 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 5065 referencedTableColumns.getObjectName(j), false); 5066 if (tableColumn != null) { 5067 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5068 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5069 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5070 relation.setEffectType(EffectType.foreign_key); 5071 Process process = modelFactory.createProcess(stmt); 5072 relation.setProcess(process); 5073 if(this.option.isShowERDiagram()){ 5074 ERRelationship erRelation = modelFactory.createERRelation(); 5075 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5076 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5077 } 5078 } 5079 } 5080 } 5081 else{ 5082 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false); 5083 if (tableColumn != null) { 5084 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5085 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5086 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5087 relation.setEffectType(EffectType.foreign_key); 5088 if(this.option.isShowERDiagram()){ 5089 ERRelationship erRelation = modelFactory.createERRelation(); 5090 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5091 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5092 } 5093 } 5094 } 5095 } 5096 } 5097 } 5098 else if (option.getConstraintList() != null) { 5099 for(int iCons=0; iCons<option.getConstraintList().size(); iCons++){ 5100 TConstraint alertTableConstraint = option.getConstraintList().getConstraint(iCons); 5101 TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList(); 5102 if(keyNames != null){ 5103 for (int k = 0; k < keyNames.size(); k++) { 5104 TObjectName keyName = keyNames.getElement(k).getColumnName(); 5105 TObjectName referencedTableName = alertTableConstraint.getReferencedObject(); 5106 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 5107 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 5108 if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){ 5109 tableConstraint.setPrimaryKey(true); 5110 } 5111 else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){ 5112 tableConstraint.setIndexKey(true); 5113 } 5114 else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){ 5115 tableConstraint.setUnqiueKey(true); 5116 } 5117 else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) { 5118 tableConstraint.setForeignKey(true); 5119 Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 5120 if (referencedTable == null) { 5121 referencedTable = modelFactory.createTableByName(referencedTableName); 5122 } 5123 TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList(); 5124 if (referencedTableColumns != null) { 5125 for (int j = 0; j < referencedTableColumns.size(); j++) { 5126 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 5127 referencedTableColumns.getObjectName(j), false); 5128 if (tableColumn != null) { 5129 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5130 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5131 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5132 relation.setEffectType(EffectType.foreign_key); 5133 Process process = modelFactory.createProcess(stmt); 5134 relation.setProcess(process); 5135 if(this.option.isShowERDiagram()){ 5136 ERRelationship erRelation = modelFactory.createERRelation(); 5137 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5138 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5139 } 5140 } 5141 } 5142 } 5143 else{ 5144 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false); 5145 if (tableColumn != null) { 5146 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5147 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5148 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5149 relation.setEffectType(EffectType.foreign_key); 5150 Process process = modelFactory.createProcess(stmt); 5151 relation.setProcess(process); 5152 if(this.option.isShowERDiagram()){ 5153 ERRelationship erRelation = modelFactory.createERRelation(); 5154 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5155 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5156 } 5157 } 5158 } 5159 } 5160 } 5161 } 5162 } 5163 } 5164 else if (option.getIndexCols() != null){ 5165 TPTNodeList<TColumnWithSortOrder> keyNames = option.getIndexCols(); 5166 for (int k = 0; k < keyNames.size(); k++) { 5167 TObjectName keyName = keyNames.getElement(k).getColumnName(); 5168 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 5169 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 5170 if(option.getOptionType() == EAlterTableOptionType.AddConstraintPK){ 5171 tableConstraint.setPrimaryKey(true); 5172 } 5173 else if(option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){ 5174 tableConstraint.setIndexKey(true); 5175 } 5176 else if(option.getOptionType() == EAlterTableOptionType.AddConstraintUnique){ 5177 tableConstraint.setUnqiueKey(true); 5178 } 5179 else if (option.getOptionType() == EAlterTableOptionType.AddConstraintFK) { 5180 TObjectName referencedTableName = option.getReferencedObjectName(); 5181 tableConstraint.setForeignKey(true); 5182 Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 5183 if (referencedTable == null) { 5184 referencedTable = modelFactory.createTableByName(referencedTableName); 5185 } 5186 TObjectNameList referencedTableColumns = option.getReferencedColumnList(); 5187 if (referencedTableColumns != null) { 5188 for (int j = 0; j < referencedTableColumns.size(); j++) { 5189 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 5190 referencedTableColumns.getObjectName(j), false); 5191 if (tableColumn != null) { 5192 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5193 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5194 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5195 relation.setEffectType(EffectType.foreign_key); 5196 Process process = modelFactory.createProcess(stmt); 5197 relation.setProcess(process); 5198 if(this.option.isShowERDiagram()){ 5199 ERRelationship erRelation = modelFactory.createERRelation(); 5200 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5201 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5202 } 5203 } 5204 } 5205 } 5206 else{ 5207 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false); 5208 if (tableColumn != null) { 5209 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5210 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5211 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5212 relation.setEffectType(EffectType.foreign_key); 5213 Process process = modelFactory.createProcess(stmt); 5214 relation.setProcess(process); 5215 if(this.option.isShowERDiagram()){ 5216 ERRelationship erRelation = modelFactory.createERRelation(); 5217 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5218 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5219 } 5220 } 5221 } 5222 } 5223 } 5224 } 5225 } 5226 } 5227 } 5228 5229 private void analyzeAlterViewStmt(TAlterViewStatement stmt) { 5230 if (stmt.getAlterViewOption() == EAlterViewOption.asSelect) { 5231 analyzeCreateViewStmt(stmt, stmt.getSelectSqlStatement(), null, stmt.getViewName()); 5232 } else { 5233 throw new UnsupportedOperationException("Can't handle this alter view statement case, alter option = "+ stmt.getAlterViewOption().name()); 5234 } 5235 } 5236 5237 private void analyzeDeleteStmt(TDeleteSqlStatement stmt) { 5238 TTable table = stmt.getTargetTable(); 5239 if (table == null) 5240 return; 5241 5242 if (table.getCTE() != null) { 5243 table = table.getCTE().getSubquery().getTables().getTable(0); 5244 } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) { 5245 table = table.getLinkTable().getSubquery().getTables().getTable(0); 5246 } else if (table.getSubquery() != null) { 5247 table = table.getSubquery().getTables().getTable(0); 5248 } 5249 5250 Table tableModel = modelFactory.createTable(table); 5251 if (getTableLinkedColumns(table) != null && getTableLinkedColumns(table).size() > 0) { 5252 for (int j = 0; j < getTableLinkedColumns(table).size(); j++) { 5253 TObjectName object = getTableLinkedColumns(table).getObjectName(j); 5254 5255 if (object.getDbObjectType() == EDbObjectType.variable) { 5256 continue; 5257 } 5258 5259 if (object.getColumnNameOnly().startsWith("@") 5260 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 5261 continue; 5262 } 5263 5264 if (object.getColumnNameOnly().startsWith(":") 5265 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 5266 continue; 5267 } 5268 5269 if (!isBuiltInFunctionName(object)) { 5270 if (object.getSourceTable() == null || object.getSourceTable() == table) { 5271 modelFactory.createTableColumn(tableModel, object, false); 5272 } 5273 } 5274 } 5275 } 5276 5277 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 5278 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 5279 crudRelationship.setTarget(new TableRelationshipElement(tableModel)); 5280 crudRelationship.setEffectType(EffectType.delete); 5281 } 5282 5283 if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) { 5284 analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where, 5285 EffectType.delete); 5286 } 5287 } 5288 5289 private TObjectName getProcedureName(TStoredProcedureSqlStatement stmt) { 5290 if (stmt instanceof TTeradataCreateProcedure) { 5291 return ((TTeradataCreateProcedure) stmt).getProcedureName(); 5292 } 5293 return stmt.getStoredProcedureName(); 5294 } 5295 5296 private void analyzePlsqlCreatePackage(TPlsqlCreatePackage stmt) { 5297 TObjectName procedureName = getProcedureName(stmt); 5298 OraclePackage oraclePackage; 5299 if (procedureName != null) { 5300 if (this.modelManager.getOraclePackageByName( 5301 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))) == null) { 5302 oraclePackage = this.modelFactory.createOraclePackage(stmt); 5303 5304 if (stmt.getParameterDeclarations() != null) { 5305 TParameterDeclarationList parameters = stmt.getParameterDeclarations(); 5306 5307 for (int i = 0; i < parameters.size(); ++i) { 5308 TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i); 5309 if (parameter.getParameterName() != null) { 5310 this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1); 5311 } else if (parameter.getDataType() != null) { 5312 this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1); 5313 } 5314 } 5315 } 5316 5317 ModelBindingManager.setGlobalOraclePackage(oraclePackage); 5318 } else { 5319 ModelBindingManager.setGlobalOraclePackage(this.modelManager.getOraclePackageByName( 5320 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt)))); 5321 } 5322 5323 try { 5324 if (stmt.getDeclareStatements() != null) { 5325 for (int i = 0; i < stmt.getDeclareStatements().size(); ++i) { 5326 analyzeCustomSqlStmt(stmt.getDeclareStatements().get(i)); 5327 } 5328 } 5329 } finally { 5330 ModelBindingManager.removeGlobalOraclePackage(); 5331 } 5332 } 5333 } 5334 5335 private void analyzeStoredProcedureStmt(TStoredProcedureSqlStatement stmt) { 5336 5337 if (stmt instanceof TPlsqlCreatePackage) { 5338 analyzePlsqlCreatePackage((TPlsqlCreatePackage) stmt); 5339 return; 5340 } 5341 5342 ModelBindingManager.setGlobalProcedure(stmt); 5343 5344 try { 5345 Procedure procedure = null; 5346 5347 TObjectName procedureName = getProcedureName(stmt); 5348 if (procedureName != null) { 5349 procedure = this.modelFactory.createProcedure(stmt); 5350 if (procedure != null) { 5351 modelManager.bindModel(stmt, procedure); 5352 } 5353 if (ModelBindingManager.getGlobalOraclePackage() != null) { 5354 ModelBindingManager.getGlobalOraclePackage().addProcedure(procedure); 5355 procedure.setParentPackage(ModelBindingManager.getGlobalOraclePackage()); 5356 } 5357 if (stmt.getParameterDeclarations() != null) { 5358 TParameterDeclarationList parameters = stmt.getParameterDeclarations(); 5359 5360 for (int i = 0; i < parameters.size(); ++i) { 5361 TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i); 5362 Argument argument = null; 5363 TObjectName argumentName = null; 5364 if (parameter.getParameterName() != null) { 5365 argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1); 5366 argumentName = parameter.getParameterName(); 5367 } else if (parameter.getDataType() != null) { 5368 argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1); 5369 } 5370 5371 if (argument != null) { 5372 if (argumentName == null) { 5373 argumentName = new TObjectName(); 5374 argumentName.setString(argument.getName()); 5375 } 5376 Variable variable = modelFactory.createVariable(argument.getName()); 5377 if (argument.getMode() == EParameterMode.in || argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 5378 variable.setSubType(SubType.of(argument.getMode().name())); 5379 } else { 5380 variable.setSubType(SubType.argument); 5381 } 5382 if(isSimpleDataType(argument.getDataType())){ 5383 modelFactory.createTableColumn(variable, argumentName, true); 5384 } 5385 else { 5386 TObjectName variableProperties = new TObjectName(); 5387 variableProperties.setString("*"); 5388 modelFactory.createTableColumn(variable, variableProperties, true); 5389 } 5390 } 5391 } 5392 } 5393 } 5394 5395 if (stmt instanceof TCreateTriggerStmt) { 5396 TCreateTriggerStmt trigger = (TCreateTriggerStmt) stmt; 5397 5398 if (trigger.getFunctionCall() != null) { 5399 modelFactory.createProcedureFromFunctionCall(trigger.getFunctionCall()); 5400 } 5401 5402 if (trigger.getTables() != null) { 5403 for (int i = 0; i < trigger.getTables().size(); i++) { 5404 Table tableModel = this.modelFactory.createTriggerOnTable(trigger.getTables().getTable(i)); 5405 } 5406 } 5407 } 5408 5409 if (stmt instanceof TPlsqlCreateTrigger 5410 && ((TPlsqlCreateTrigger) stmt).getTriggeringClause().getEventClause() instanceof TDmlEventClause) { 5411 TPlsqlCreateTrigger trigger = (TPlsqlCreateTrigger) stmt; 5412 TDmlEventClause clause = (TDmlEventClause) ((TPlsqlCreateTrigger) stmt).getTriggeringClause() 5413 .getEventClause(); 5414 Table sourceTable = modelFactory.createTableByName(clause.getTableName()); 5415 5416 for (TTriggerEventItem item : clause.getEventItems()) { 5417 if (item instanceof TDmlEventItem) { 5418 if (((TDmlEventItem) item).getColumnList() != null) { 5419 for (TObjectName column : ((TDmlEventItem) item).getColumnList()) { 5420 modelFactory.createTableColumn(sourceTable, column, true); 5421 } 5422 } 5423 } 5424 } 5425 5426 for (TCustomSqlStatement subStmt : ((TPlsqlCreateTrigger) stmt).getStatements()) { 5427 if (!(subStmt instanceof TCommonBlock)) 5428 continue; 5429 for (TCustomSqlStatement blockSubStmt : ((TCommonBlock) subStmt).getStatements()) { 5430 if (!(blockSubStmt instanceof TBasicStmt)) 5431 continue; 5432 TBasicStmt basicStmt = (TBasicStmt) blockSubStmt; 5433 TExpression expression = basicStmt.getExpr(); 5434 if (expression != null && expression.getExpressionType() == EExpressionType.function_t) { 5435 Procedure targetProcedure = modelManager.getProcedureByName(DlineageUtil 5436 .getTableFullName(expression.getFunctionCall().getFunctionName().toString())); 5437 if (targetProcedure == null) { 5438 targetProcedure = modelManager 5439 .getProcedureByName(DlineageUtil.getTableFullName(procedure.getSchema() + "." 5440 + expression.getFunctionCall().getFunctionName().toString())); 5441 } 5442 if (targetProcedure != null && expression.getFunctionCall().getArgs() != null && expression 5443 .getFunctionCall().getArgs().size() == targetProcedure.getArguments().size()) { 5444 for (int j = 0; j < expression.getFunctionCall().getArgs().size(); j++) { 5445 TExpression columnExpr = expression.getFunctionCall().getArgs().getExpression(j); 5446 if (columnExpr.getExpressionType() == EExpressionType.simple_object_name_t) { 5447 TObjectName columnObject = columnExpr.getObjectOperand(); 5448 if (columnObject.toString().indexOf(":") != -1) { 5449 TableColumn tableColumn = modelFactory.createTableColumn(sourceTable, 5450 columnObject, true); 5451 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5452 relation.setEffectType(EffectType.trigger); 5453 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5454 relation.setTarget( 5455 new ArgumentRelationshipElement(targetProcedure.getArguments().get(j))); 5456 Process process = modelFactory.createProcess(stmt); 5457 relation.setProcess(process); 5458 } 5459 } 5460 } 5461 } 5462 } 5463 } 5464 } 5465 } 5466 5467 if (stmt instanceof TMssqlCreateFunction) { 5468 TMssqlCreateFunction createFunction = (TMssqlCreateFunction) stmt; 5469 if (createFunction.getReturnTableVaraible() != null && createFunction.getReturnTableDefinitions() != null) { 5470 Variable tableModel = this.modelFactory.createVariable(createFunction.getReturnTableVaraible()); 5471 tableModel.setVariable(true); 5472 tableModel.setCreateTable(true); 5473 String procedureParent = createFunction.getFunctionName().toString(); 5474 if (procedureParent != null) { 5475 tableModel.setParent(procedureParent); 5476 } 5477 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 5478 5479 if (createFunction.getReturnTableDefinitions() != null) { 5480 for (int j = 0; j < createFunction.getReturnTableDefinitions().size(); j++) { 5481 TTableElement tableElement = createFunction.getReturnTableDefinitions().getTableElement(j); 5482 TColumnDefinition column = tableElement.getColumnDefinition(); 5483 if (column != null && column.getColumnName() != null) { 5484 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 5485 } 5486 } 5487 } 5488 } 5489 5490 if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) { 5491 String procedureParent = createFunction.getFunctionName().toString(); 5492 analyzeSelectStmt(createFunction.getReturnStmt().getSubquery()); 5493 ResultSet resultSetModel = (ResultSet) modelManager 5494 .getModel(createFunction.getReturnStmt().getSubquery()); 5495 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5496 resultSetModel); 5497 } 5498 } else if (stmt instanceof TCreateFunctionStmt) { 5499 TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt; 5500 if (createFunction.getReturnDataType() != null 5501 && createFunction.getReturnDataType().getColumnDefList() != null) { 5502 Table tableModel = this.modelFactory.createTableByName(createFunction.getFunctionName(), true); 5503 tableModel.setCreateTable(true); 5504 String procedureParent = createFunction.getFunctionName().toString(); 5505 if (procedureParent != null) { 5506 tableModel.setParent(procedureParent); 5507 } 5508 5509 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 5510 for (int j = 0; j < createFunction.getReturnDataType().getColumnDefList().size(); j++) { 5511 TColumnDefinition column = createFunction.getReturnDataType().getColumnDefList().getColumn(j); 5512 if (column != null && column.getColumnName() != null) { 5513 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 5514 } 5515 } 5516 5517 if (createFunction.getSqlQuery() != null) { 5518 analyzeSelectStmt(createFunction.getSqlQuery()); 5519 ResultSet resultSetModel = (ResultSet) modelManager.getModel(createFunction.getSqlQuery()); 5520 if (resultSetModel != null) { 5521 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 5522 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 5523 for (int j = 0; j < tableModel.getColumns().size(); j++) { 5524 TableColumn tableColumn = tableModel.getColumns().get(j); 5525 if (DlineageUtil.compareColumnIdentifier(getColumnName(resultColumn.getName()), 5526 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 5527 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 5528 dataflowRelation.setEffectType(EffectType.select); 5529 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 5530 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 5531 } 5532 } 5533 } 5534 } 5535 } 5536 } 5537 5538 if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) { 5539 String procedureParent = createFunction.getFunctionName().toString(); 5540 analyzeSelectStmt(createFunction.getReturnStmt().getSubquery()); 5541 ResultSet resultSetModel = (ResultSet) modelManager 5542 .getModel(createFunction.getReturnStmt().getSubquery()); 5543 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5544 resultSetModel); 5545 } 5546 5547 if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getReturnExpr() != null) { 5548 TExpression returnExpression = createFunction.getReturnStmt().getReturnExpr(); 5549 ResultSet returnResult = modelFactory.createResultSet(createFunction.getReturnStmt(), false); 5550 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 5551 5552 TExpression expression = createFunction.getReturnStmt().getReturnExpr(); 5553 analyzeResultColumnExpressionRelation(resultColumn, expression); 5554 5555 String procedureParent = createFunction.getFunctionName().toString(); 5556 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5557 returnResult); 5558 } 5559 } 5560 5561 if (stmt instanceof TCreateProcedureStmt) { 5562 TCreateProcedureStmt createProcedure = (TCreateProcedureStmt) stmt; 5563 if (EDbVendor.dbvsnowflake == option.getVendor() && createProcedure.getRoutineBodyInConstant() != null) { 5564 extractSnowflakeSQLFromProcedure(createProcedure); 5565 } 5566 } 5567 5568 if (stmt.getStatements().size() > 0) { 5569 for (int i = 0; i < stmt.getStatements().size(); ++i) { 5570 this.analyzeCustomSqlStmt(stmt.getStatements().get(i)); 5571 } 5572 } 5573 5574 if (stmt.getBodyStatements().size() > 0) { 5575 for (int i = 0; i < stmt.getBodyStatements().size(); ++i) { 5576 this.analyzeCustomSqlStmt(stmt.getBodyStatements().get(i)); 5577 } 5578 } 5579 5580 // Detect pipelined functions and build signatures 5581 if (stmt instanceof TPlsqlCreateFunction && pipelinedAnalyzer != null) { 5582 try { 5583 pipelinedAnalyzer.analyzePipelinedFunction((TPlsqlCreateFunction) stmt); 5584 } catch (Exception e) { 5585 // Don't let pipelined analysis failure break main flow 5586 } 5587 } 5588 5589 if (procedure != null && !getLastSelectStmt(stmt).isEmpty()) { 5590 for (TSelectSqlStatement select : getLastSelectStmt(stmt)) { 5591 ResultSet resultSet = (ResultSet) modelManager.getModel(select); 5592 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedure.getName()), 5593 resultSet); 5594 } 5595// List<Argument> outArgs = new ArrayList<Argument>(); 5596// for (int i = 0; i < procedure.getArguments().size(); i++) { 5597// Argument argument = procedure.getArguments().get(i); 5598// if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 5599// outArgs.add(argument); 5600// } 5601// } 5602// 5603// if (resultSet != null && resultSet.getColumns().size() == outArgs.size()) { 5604// for (int i = 0; i < outArgs.size(); i++) { 5605// Argument argument = outArgs.get(i); 5606// Variable variable = modelFactory.createVariable(argument.getName(), false); 5607// if (variable != null) { 5608// DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 5609// dataflowRelation.setEffectType(EffectType.output); 5610// dataflowRelation 5611// .addSource(new ResultColumnRelationshipElement(resultSet.getColumns().get(i))); 5612// dataflowRelation 5613// .setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0))); 5614// } 5615// } 5616// 5617// } 5618 } 5619 5620 if (stmt instanceof TCreateFunctionStmt && ((TCreateFunctionStmt)stmt).getSqlExpression()!=null) { 5621 TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt; 5622 TExpression returnExpression = createFunction.getSqlExpression(); 5623 5624 ResultSet returnResult = modelFactory.createResultSet(stmt, false); 5625 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 5626 5627 columnsInExpr visitor = new columnsInExpr(); 5628 returnExpression.inOrderTraverse(visitor); 5629 5630 List<TObjectName> objectNames = visitor.getObjectNames(); 5631 List<TParseTreeNode> functions = visitor.getFunctions(); 5632 List<TParseTreeNode> constants = visitor.getConstants(); 5633 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 5634 5635 if (functions != null && !functions.isEmpty()) { 5636 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 5637 } 5638 if (subquerys != null && !subquerys.isEmpty()) { 5639 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 5640 } 5641 if (objectNames != null && !objectNames.isEmpty()) { 5642 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 5643 } 5644 if (constants != null && !constants.isEmpty()) { 5645 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 5646 } 5647 5648 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 5649 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5650 returnResult); 5651 } 5652 } finally { 5653 ModelBindingManager.removeGlobalProcedure(); 5654 } 5655 5656 } 5657 5658 private boolean isSimpleDataType(TTypeName dataType) { 5659 if (dataType.getDataType() == EDataType.variant_t) { 5660 return false; 5661 } 5662 if (dataType.getDataType() == EDataType.cursor_t) { 5663 return false; 5664 } 5665 if (dataType.getDataType() == EDataType.generic_t) { 5666 return false; 5667 } 5668 if (dataType.getDataType() == EDataType.unknown_t) { 5669 return false; 5670 } 5671 if (dataType.getDataType() == EDataType.sql_variant_t) { 5672 return false; 5673 } 5674 if (dataType.getDataType() == EDataType.table_t) { 5675 return false; 5676 } 5677 if (dataType.getDataType() == EDataType.raw_t) { 5678 return false; 5679 } 5680 if (dataType.getDataType() == EDataType.resultset_t) { 5681 return false; 5682 } 5683 if (dataType.getDataType() == EDataType.row_t) { 5684 return false; 5685 } 5686 if (dataType.getDataType() == EDataType.map_t) { 5687 return false; 5688 } 5689 if (dataType.getDataType() == EDataType.anyType_t) { 5690 return false; 5691 } 5692 if (dataType.getDataType() == EDataType.struct_t) { 5693 return false; 5694 } 5695 if (dataType.getDataType() == EDataType.structType_t) { 5696 return false; 5697 } 5698 if (dataType.getDataType() == EDataType.mapType_t) { 5699 return false; 5700 } 5701 return true; 5702 } 5703 5704 protected void analyzeResultColumnExpressionRelation(Object resultColumn, TExpression expression) { 5705 columnsInExpr visitor = new columnsInExpr(); 5706 expression.inOrderTraverse(visitor); 5707 List<TObjectName> objectNames = visitor.getObjectNames(); 5708 List<TParseTreeNode> functions = visitor.getFunctions(); 5709 List<TParseTreeNode> constants = visitor.getConstants(); 5710 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 5711 5712 if (functions != null && !functions.isEmpty()) { 5713 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 5714 } 5715 if (subquerys != null && !subquerys.isEmpty()) { 5716 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 5717 } 5718 if (objectNames != null && !objectNames.isEmpty()) { 5719 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 5720 } 5721 if (constants != null && !constants.isEmpty()) { 5722 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 5723 } 5724 } 5725 5726 private void analyzeDb2ReturnStmt(TDb2ReturnStmt stmt) { 5727 if (stmt.getReturnExpr() != null) { 5728 TExpression returnExpression = stmt.getReturnExpr(); 5729 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 5730 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 5731 5732 columnsInExpr visitor = new columnsInExpr(); 5733 stmt.getReturnExpr().inOrderTraverse(visitor); 5734 5735 List<TObjectName> objectNames = visitor.getObjectNames(); 5736 List<TParseTreeNode> functions = visitor.getFunctions(); 5737 List<TParseTreeNode> constants = visitor.getConstants(); 5738 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 5739 5740 if (functions != null && !functions.isEmpty()) { 5741 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 5742 } 5743 if (subquerys != null && !subquerys.isEmpty()) { 5744 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 5745 } 5746 if (objectNames != null && !objectNames.isEmpty()) { 5747 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 5748 } 5749 if (constants != null && !constants.isEmpty()) { 5750 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 5751 } 5752 5753 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 5754 if (procedureParent != null) { 5755 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5756 returnResult); 5757 } 5758 } 5759 } 5760 5761 private void analyzeReturnStmt(TReturnStmt stmt) { 5762 if (stmt.getResultColumnList() != null) { 5763 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 5764 for (TResultColumn column : stmt.getResultColumnList()) { 5765 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column); 5766 5767 columnsInExpr visitor = new columnsInExpr(); 5768 column.getExpr().inOrderTraverse(visitor); 5769 5770 List<TObjectName> objectNames = visitor.getObjectNames(); 5771 List<TParseTreeNode> functions = visitor.getFunctions(); 5772 List<TParseTreeNode> constants = visitor.getConstants(); 5773 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 5774 5775 if (functions != null && !functions.isEmpty()) { 5776 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 5777 } 5778 if (subquerys != null && !subquerys.isEmpty()) { 5779 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 5780 } 5781 if (objectNames != null && !objectNames.isEmpty()) { 5782 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 5783 } 5784 if (constants != null && !constants.isEmpty()) { 5785 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 5786 } 5787 5788 } 5789 5790 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 5791 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5792 returnResult); 5793 } 5794 else if(stmt.getExpression()!=null){ 5795 TExpression returnExpression = stmt.getExpression(); 5796 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 5797 5798 columnsInExpr visitor = null; 5799 List<TSelectSqlStatement> subquerys = null; 5800 5801 if (returnExpression.getFunctionCall() != null 5802 && returnExpression.getFunctionCall().getFunctionName().toString().equalsIgnoreCase("table") 5803 && returnExpression.getFunctionCall().getArgs() != null 5804 && returnExpression.getFunctionCall().getArgs().size()>0) { 5805 visitor = new columnsInExpr(); 5806 returnExpression.getFunctionCall().getArgs().getExpression(0).inOrderTraverse(visitor); 5807 subquerys = visitor.getSubquerys(); 5808 if (subquerys != null && !subquerys.isEmpty()) { 5809 analyzeSelectStmt(subquerys.get(0)); 5810 ResultSet resultSet = (ResultSet) modelManager.getModel(subquerys.get(0)); 5811 if (resultSet != null && resultSet.getColumns() != null) { 5812 for (ResultColumn column : resultSet.getColumns()) { 5813 TObjectName columnName = new TObjectName(); 5814 columnName.setString(column.getName()); 5815 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, columnName); 5816 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 5817 dataflowRelation.setEffectType(EffectType.select); 5818 dataflowRelation.addSource(new ResultColumnRelationshipElement(column)); 5819 dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 5820 } 5821 } 5822 returnResult.setDetermined(resultSet.isDetermined()); 5823 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 5824 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5825 returnResult); 5826 return; 5827 } 5828 } 5829 5830 ResultColumn resultColumn = null; 5831 if (returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) { 5832 TObjectName columnName = new TObjectName(); 5833 columnName.setString("*"); 5834 resultColumn = modelFactory.createResultColumn(returnResult, columnName); 5835 } 5836 else { 5837 resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 5838 } 5839 5840 visitor = new columnsInExpr(); 5841 stmt.getExpression().inOrderTraverse(visitor); 5842 5843 List<TObjectName> objectNames = visitor.getObjectNames(); 5844 List<TParseTreeNode> functions = visitor.getFunctions(); 5845 List<TParseTreeNode> constants = visitor.getConstants(); 5846 subquerys = visitor.getSubquerys(); 5847 5848 if (functions != null && !functions.isEmpty()) { 5849 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 5850 } 5851 if (subquerys != null && !subquerys.isEmpty()) { 5852 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 5853 } 5854 if (objectNames != null && !objectNames.isEmpty()) { 5855 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 5856 //如果variable对应的不是一个复杂结构,则resultColumn不要设置为* 5857 if (relation != null && relation.getTarget().getElement() == resultColumn && relation.getSources().size() == 1) { 5858 Object column = relation.getSources().iterator().next().getElement(); 5859 boolean star = true; 5860 if (column instanceof TableColumn && ((TableColumn) column).getName().indexOf("*") == -1) { 5861 star = false; 5862 } 5863 if (column instanceof ResultColumn && ((ResultColumn) column).getName().indexOf("*") == -1) { 5864 star = false; 5865 } 5866 if (!star && returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) { 5867 resultColumn = modelFactory.createResultColumn(returnResult, returnExpression.getObjectOperand()); 5868 returnResult.getColumns().clear(); 5869 returnResult.addColumn(resultColumn); 5870 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 5871 } 5872 } 5873 } 5874 if (constants != null && !constants.isEmpty()) { 5875 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 5876 } 5877 5878 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 5879 if (procedureParent != null) { 5880 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5881 returnResult); 5882 } 5883 } 5884 } 5885 5886 private void analyzeMssqlReturnStmt(TMssqlReturn stmt) { 5887 if (stmt.getResultColumnList() != null) { 5888 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 5889 for (TResultColumn column : stmt.getResultColumnList()) { 5890 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column); 5891 5892 columnsInExpr visitor = new columnsInExpr(); 5893 column.getExpr().inOrderTraverse(visitor); 5894 5895 List<TObjectName> objectNames = visitor.getObjectNames(); 5896 List<TParseTreeNode> functions = visitor.getFunctions(); 5897 List<TParseTreeNode> constants = visitor.getConstants(); 5898 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 5899 5900 if (functions != null && !functions.isEmpty()) { 5901 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 5902 } 5903 if (subquerys != null && !subquerys.isEmpty()) { 5904 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 5905 } 5906 if (objectNames != null && !objectNames.isEmpty()) { 5907 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 5908 } 5909 if (constants != null && !constants.isEmpty()) { 5910 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 5911 } 5912 5913 } 5914 5915 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 5916 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5917 returnResult); 5918 } 5919 else if(stmt.getReturnExpr()!=null){ 5920 TExpression returnExpression = stmt.getReturnExpr(); 5921 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 5922 5923 if (returnExpression.getSubQuery() == null) { 5924 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 5925 columnsInExpr visitor = new columnsInExpr(); 5926 stmt.getReturnExpr().inOrderTraverse(visitor); 5927 5928 List<TObjectName> objectNames = visitor.getObjectNames(); 5929 List<TParseTreeNode> functions = visitor.getFunctions(); 5930 List<TParseTreeNode> constants = visitor.getConstants(); 5931 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 5932 5933 if (functions != null && !functions.isEmpty()) { 5934 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 5935 } 5936 if (subquerys != null && !subquerys.isEmpty()) { 5937 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 5938 } 5939 if (objectNames != null && !objectNames.isEmpty()) { 5940 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 5941 } 5942 if (constants != null && !constants.isEmpty()) { 5943 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 5944 } 5945 } 5946 else { 5947 analyzeSelectStmt(returnExpression.getSubQuery()); 5948 ResultSet subResultSet = (ResultSet)modelManager.getModel(returnExpression.getSubQuery()); 5949 if (subResultSet != null) { 5950 for (ResultColumn subResultColumn : subResultSet.getColumns()) { 5951 TObjectName objectName = new TObjectName(); 5952 objectName.setString(subResultColumn.getName()); 5953 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, objectName); 5954 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 5955 dataflowRelation.setEffectType(EffectType.select); 5956 dataflowRelation.addSource(new ResultColumnRelationshipElement(subResultColumn)); 5957 dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 5958 5959 } 5960 5961 if(subResultSet.getRelationRows().hasRelation()) { 5962 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 5963 impactRelation.setEffectType(EffectType.select); 5964 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 5965 subResultSet.getRelationRows())); 5966 impactRelation.setTarget( 5967 new RelationRowsRelationshipElement<ResultSetRelationRows>(returnResult.getRelationRows())); 5968 } 5969 } 5970 } 5971 5972 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 5973 if (procedureParent != null) { 5974 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 5975 returnResult); 5976 } 5977 } 5978 } 5979 5980 private void analyzeFetchStmt(TFetchStmt stmt) { 5981 if (stmt.getVariableNames() != null) { 5982 for (int i = 0; i < stmt.getVariableNames().size(); i++) { 5983 TExpression variableExpression = stmt.getVariableNames().getExpression(i); 5984 if (variableExpression.getExpressionType() == EExpressionType.simple_object_name_t) { 5985 TObjectName columnObject = variableExpression.getObjectOperand(); 5986 if (columnObject.getDbObjectType() == EDbObjectType.variable) { 5987 continue; 5988 } 5989 5990 if (columnObject.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql 5991 || option.getVendor() == EDbVendor.dbvazuresql)) { 5992 continue; 5993 } 5994 5995 if (columnObject.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana 5996 || option.getVendor() == EDbVendor.dbvteradata)) { 5997 continue; 5998 } 5999 6000 Variable cursorVariable = modelFactory.createVariable(columnObject); 6001 cursorVariable.setSubType(SubType.record); 6002 if (cursorVariable.isDetermined()) { 6003 if (stmt.getCursorName() != null) { 6004 String procedureName = DlineageUtil.getProcedureParentName(stmt); 6005 String variableString = stmt.getCursorName().toString(); 6006 if (variableString.startsWith(":")) { 6007 variableString = variableString.substring(variableString.indexOf(":") + 1); 6008 } 6009 if (!SQLUtil.isEmpty(procedureName)) { 6010 variableString = procedureName + "." 6011 + SQLUtil.getIdentifierNormalTableName(variableString); 6012 } 6013 Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 6014 if (cursor != null) { 6015 for (TableColumn variableProperty : cursorVariable.getColumns()) { 6016 boolean flag = false; 6017 for (TableColumn cursorColumn : cursor.getColumns()) { 6018 if (getColumnName(cursorColumn.getName()) 6019 .equalsIgnoreCase(variableProperty.getName())) { 6020 DataFlowRelationship dataflowRelation = modelFactory 6021 .createDataFlowRelation(); 6022 dataflowRelation.setEffectType(EffectType.cursor); 6023 dataflowRelation 6024 .addSource(new TableColumnRelationshipElement(cursorColumn)); 6025 dataflowRelation 6026 .setTarget(new TableColumnRelationshipElement(variableProperty)); 6027 flag = true; 6028 break; 6029 } 6030 } 6031 6032 if (!flag) { 6033 if (cursor.getColumns().size() == stmt.getVariableNames().size()) { 6034 DataFlowRelationship dataflowRelation = modelFactory 6035 .createDataFlowRelation(); 6036 dataflowRelation.setEffectType(EffectType.cursor); 6037 dataflowRelation 6038 .setTarget(new TableColumnRelationshipElement(variableProperty)); 6039 dataflowRelation.addSource( 6040 new TableColumnRelationshipElement(cursor.getColumns().get(i))); 6041 } 6042 else { 6043 for (int j = 0; j < cursor.getColumns().size(); j++) { 6044 DataFlowRelationship dataflowRelation = modelFactory 6045 .createDataFlowRelation(); 6046 dataflowRelation.setEffectType(EffectType.cursor); 6047 if (stmt.getVariableNames().size() == 1) { 6048 dataflowRelation.addSource(new TableColumnRelationshipElement( 6049 cursor.getColumns().get(j))); 6050 } else { 6051 dataflowRelation.addSource(new TableColumnRelationshipElement( 6052 cursor.getColumns().get(j), i)); 6053 } 6054 dataflowRelation.setTarget( 6055 new TableColumnRelationshipElement(variableProperty)); 6056 } 6057 } 6058 } 6059 } 6060 } 6061 } 6062 6063 } else { 6064 TableColumn variableProperty = null; 6065 if (stmt.getVariableNames().size() == 1) { 6066 if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) { 6067 TObjectName starColumn = new TObjectName(); 6068 starColumn.setString("*"); 6069 variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 6070 } else { 6071 variableProperty = cursorVariable.getColumns().get(0); 6072 } 6073 } else { 6074 variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true); 6075 } 6076 6077 if (stmt.getCursorName() != null) { 6078 String procedureName = DlineageUtil.getProcedureParentName(stmt); 6079 String variableString = stmt.getCursorName().toString(); 6080 if (variableString.startsWith(":")) { 6081 variableString = variableString.substring(variableString.indexOf(":") + 1); 6082 } 6083 if (!SQLUtil.isEmpty(procedureName)) { 6084 variableString = procedureName + "." 6085 + SQLUtil.getIdentifierNormalTableName(variableString); 6086 } 6087 Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 6088 if (cursor != null) { 6089 for (int j = 0; j < cursor.getColumns().size(); j++) { 6090 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6091 dataflowRelation.setEffectType(EffectType.cursor); 6092 if (stmt.getVariableNames().size() == 1) { 6093 dataflowRelation.addSource( 6094 new TableColumnRelationshipElement(cursor.getColumns().get(j))); 6095 } else { 6096 dataflowRelation.addSource( 6097 new TableColumnRelationshipElement(cursor.getColumns().get(j), i)); 6098 } 6099 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6100 } 6101 } 6102 } 6103 } 6104 } 6105 } 6106 } 6107 } 6108 6109 private void analyzeFetchStmt(TMssqlFetch stmt) { 6110 if (stmt.getVariableNames() != null) { 6111 for (int i = 0; i < stmt.getVariableNames().size(); i++) { 6112 TObjectName columnObject = stmt.getVariableNames().getObjectName(i); 6113 Variable cursorVariable = modelFactory.createVariable(columnObject); 6114 cursorVariable.setCreateTable(true); 6115 cursorVariable.setSubType(SubType.record); 6116 TableColumn variableProperty = null; 6117 if (stmt.getVariableNames().size() == 1) { 6118 if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) { 6119 TObjectName starColumn = new TObjectName(); 6120 starColumn.setString("*"); 6121 variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 6122 } else { 6123 variableProperty = cursorVariable.getColumns().get(0); 6124 } 6125 } else { 6126 variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true); 6127 } 6128 6129 if (stmt.getCursorName() != null) { 6130 String procedureName = DlineageUtil.getProcedureParentName(stmt); 6131 String variableString = stmt.getCursorName().toString(); 6132 if (variableString.startsWith(":")) { 6133 variableString = variableString.substring(variableString.indexOf(":") + 1); 6134 } 6135 if (!SQLUtil.isEmpty(procedureName)) { 6136 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 6137 } 6138 Table cursor = modelManager 6139 .getTableByName(DlineageUtil.getTableFullName(variableString)); 6140 if (cursor != null) { 6141 for (int j = 0; j < cursor.getColumns().size(); j++) { 6142 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6143 dataflowRelation.setEffectType(EffectType.cursor); 6144 if (stmt.getVariableNames().size() == 1) { 6145 dataflowRelation 6146 .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j))); 6147 } else { 6148 dataflowRelation 6149 .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j), i)); 6150 } 6151 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6152 } 6153 } 6154 } 6155 } 6156 6157 } 6158 } 6159 6160 private void analyzeLoopStmt(TLoopStmt stmt) { 6161 6162 if (stmt.getCursorName() != null && stmt.getIndexName() != null) { 6163 modelManager.bindCursorIndex(stmt.getIndexName(), stmt.getCursorName()); 6164 } 6165 6166 if (stmt.getRecordName() != null && stmt.getSubquery() != null) { 6167 Variable cursorTempTable = modelFactory.createCursor(stmt); 6168 cursorTempTable.setVariable(true); 6169 cursorTempTable.setSubType(SubType.cursor); 6170 modelManager.bindCursorModel(stmt, cursorTempTable); 6171 analyzeSelectStmt(stmt.getSubquery()); 6172 6173 TableColumn cursorColumn = null; 6174 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 6175 TObjectName starColumn = new TObjectName(); 6176 starColumn.setString("*"); 6177 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6178 } else { 6179 cursorColumn = cursorTempTable.getColumns().get(0); 6180 } 6181 6182 6183 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 6184 if (resultSetModel != null) { 6185 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6186 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6187 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6188 dataflowRelation.setEffectType(EffectType.cursor); 6189 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6190 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6191 } 6192 } 6193 } 6194 6195 for (int i = 0; i < stmt.getStatements().size(); i++) { 6196 analyzeCustomSqlStmt(stmt.getStatements().get(i)); 6197 } 6198 } 6199 6200 private void analyzeForStmt(TForStmt stmt) { 6201 if (stmt.getSubquery() == null) { 6202 return; 6203 } 6204 6205 Variable cursorTempTable = modelFactory.createCursor(stmt); 6206 cursorTempTable.setVariable(true); 6207 cursorTempTable.setSubType(SubType.cursor); 6208 cursorTempTable.setCreateTable(true); 6209 modelManager.bindCursorModel(stmt, cursorTempTable); 6210 analyzeSelectStmt(stmt.getSubquery()); 6211 6212 TableColumn cursorColumn = null; 6213 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 6214 TObjectName starColumn = new TObjectName(); 6215 starColumn.setString("*"); 6216 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6217 } else { 6218 cursorColumn = cursorTempTable.getColumns().get(0); 6219 } 6220 6221 6222 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 6223 if (resultSetModel != null) { 6224 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6225 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6226 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6227 dataflowRelation.setEffectType(EffectType.cursor); 6228 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6229 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6230 } 6231 } 6232 6233 if (stmt.getStatements() != null && stmt.getStatements().size() > 0) { 6234 for (int i = 0; i < stmt.getStatements().size(); i++) { 6235 analyzeCustomSqlStmt(stmt.getStatements().get(i)); 6236 } 6237 } 6238 } 6239 6240 private void analyzeVarDeclStmt(TVarDeclStmt stmt) { 6241 TTypeName typeName = stmt.getDataType(); 6242 if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) { 6243 Variable cursorVariable = modelFactory.createVariable(stmt.getElementName()); 6244 cursorVariable.setSubType(SubType.record_type); 6245 6246 Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false); 6247 if(!variableTable.isCreateTable()) { 6248 TObjectName starColumn1 = new TObjectName(); 6249 starColumn1.setString("*"); 6250 TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true); 6251 variableTableStarColumn.setShowStar(false); 6252 variableTableStarColumn.setExpandStar(true); 6253 6254 TObjectName starColumn = new TObjectName(); 6255 starColumn.setString("*"); 6256 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 6257 variableProperty.setShowStar(false); 6258 variableProperty.setExpandStar(true); 6259 6260 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6261 dataflowRelation.setEffectType(EffectType.rowtype); 6262 dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn)); 6263 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6264 } else { 6265 for (TableColumn sourceColumn : variableTable.getColumns()) { 6266 String columnName = sourceColumn.getName(); 6267 TObjectName targetColumn = new TObjectName(); 6268 targetColumn.setString(columnName); 6269 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true); 6270 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6271 dataflowRelation.setEffectType(EffectType.rowtype); 6272 dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn)); 6273 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6274 } 6275 } 6276 } else if (stmt.getElementName() != null) { 6277 Variable variable = modelFactory.createVariable(stmt.getElementName()); 6278 variable.setCreateTable(true); 6279 variable.setSubType(SubType.record); 6280 TableColumn tableColumn = null; 6281 if (stmt.getDataType() != null && (modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false)!=null || isCursorType(stmt.getDataType().getDataTypeName()))) { 6282 Variable cursorVariable = modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false); 6283 if (cursorVariable != null) { 6284 if (cursorVariable.getSubType() == SubType.record_type) { 6285 variable.setSubType(SubType.record_type); 6286 } 6287 if(cursorVariable.isDetermined()) { 6288 for (int k = 0; k < cursorVariable.getColumns().size(); k++) { 6289 TableColumn sourceColumn = cursorVariable.getColumns().get(k); 6290 TObjectName objectName = new TObjectName(); 6291 objectName.setString(sourceColumn.getName()); 6292 tableColumn = modelFactory.createTableColumn(variable, objectName, true); 6293 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6294 dataflowRelation.setEffectType(EffectType.cursor); 6295 dataflowRelation 6296 .addSource(new TableColumnRelationshipElement(sourceColumn)); 6297 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 6298 } 6299 variable.setDetermined(true); 6300 return; 6301 } 6302 else { 6303 TObjectName objectName = new TObjectName(); 6304 objectName.setString("*"); 6305 tableColumn = modelFactory.createTableColumn(variable, objectName, true); 6306 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6307 dataflowRelation.setEffectType(EffectType.cursor); 6308 dataflowRelation 6309 .addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0))); 6310 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 6311 } 6312 } 6313 else { 6314 TObjectName objectName = new TObjectName(); 6315 objectName.setString("*"); 6316 tableColumn = modelFactory.createTableColumn(variable, objectName, true); 6317 } 6318 } else { 6319 tableColumn = modelFactory.createTableColumn(variable, stmt.getElementName(), true); 6320 tableColumn.setVariant(true); 6321 } 6322 6323 if (stmt.getDefaultValue() != null) { 6324 columnsInExpr visitor = new columnsInExpr(); 6325 stmt.getDefaultValue().inOrderTraverse(visitor); 6326 List<TObjectName> objectNames = visitor.getObjectNames(); 6327 List<TParseTreeNode> functions = visitor.getFunctions(); 6328 List<TParseTreeNode> constants = visitor.getConstants(); 6329 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6330 6331 if (functions != null && !functions.isEmpty()) { 6332 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6333 } 6334 if (subquerys != null && !subquerys.isEmpty()) { 6335 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6336 } 6337 if (objectNames != null && !objectNames.isEmpty()) { 6338 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6339 } 6340 if (constants != null && !constants.isEmpty()) { 6341 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6342 } 6343 } 6344 6345 6346 } 6347 } 6348 6349 private boolean isCursorType(String dataTypeName) { 6350 if (dataTypeName != null && dataTypeName.toLowerCase().contains("cursor")) { 6351 return true; 6352 } 6353 return false; 6354 } 6355 6356 private void analyzeSetStmt(TSetStmt stmt) { 6357 TExpression right = stmt.getVariableValue(); 6358 TObjectName columnObject = stmt.getVariableName(); 6359 if (columnObject != null) { 6360 TableColumn tableColumn = null; 6361 Variable tableModel; 6362 if (columnObject.toString().indexOf(".") != -1) { 6363 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6364 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 6365 } else { 6366 tableModel = modelFactory.createVariable(columnObject); 6367 } 6368 tableModel.setCreateTable(true); 6369 tableModel.setSubType(SubType.record); 6370 6371 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 6372 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 6373 } else { 6374 tableColumn = tableModel.getColumns().get(0); 6375 } 6376 6377 if (tableColumn != null && right!=null) { 6378 columnsInExpr visitor = new columnsInExpr(); 6379 right.inOrderTraverse(visitor); 6380 List<TObjectName> objectNames = visitor.getObjectNames(); 6381 List<TParseTreeNode> functions = visitor.getFunctions(); 6382 List<TParseTreeNode> constants = visitor.getConstants(); 6383 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6384 6385 if (functions != null && !functions.isEmpty()) { 6386 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6387 } 6388 if (subquerys != null && !subquerys.isEmpty()) { 6389 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6390 } 6391 if (objectNames != null && !objectNames.isEmpty()) { 6392 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6393 } 6394 if (constants != null && !constants.isEmpty()) { 6395 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6396 } 6397 6398 if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) { 6399 ModelBindingManager.setGlobalSchema(constants.get(0).toString()); 6400 } 6401 } 6402 } 6403 6404 if(stmt.getAssignments()!=null){ 6405 for (int i = 0; i < stmt.getAssignments().size(); i++) { 6406 TSetAssignment assignStmt = stmt.getAssignments().getElement(i); 6407 analyzeSetAssignmentStmt(assignStmt); 6408 } 6409 } 6410 } 6411 6412 private void analyzeSetAssignmentStmt(TSetAssignment stmt) { 6413 TExpression right = stmt.getParameterValue(); 6414 TObjectName columnObject = stmt.getParameterName(); 6415 if (columnObject != null) { 6416 TableColumn tableColumn = null; 6417 Variable tableModel; 6418 if (columnObject.toString().indexOf(".") != -1) { 6419 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6420 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 6421 } else { 6422 tableModel = modelFactory.createVariable(columnObject); 6423 } 6424 tableModel.setCreateTable(true); 6425 tableModel.setSubType(SubType.record); 6426 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 6427 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 6428 } else { 6429 tableColumn = tableModel.getColumns().get(0); 6430 } 6431 6432 if (tableColumn != null && right!=null) { 6433 columnsInExpr visitor = new columnsInExpr(); 6434 right.inOrderTraverse(visitor); 6435 List<TObjectName> objectNames = visitor.getObjectNames(); 6436 List<TParseTreeNode> functions = visitor.getFunctions(); 6437 List<TParseTreeNode> constants = visitor.getConstants(); 6438 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6439 6440 if (functions != null && !functions.isEmpty()) { 6441 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6442 } 6443 if (subquerys != null && !subquerys.isEmpty()) { 6444 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6445 } 6446 if (objectNames != null && !objectNames.isEmpty()) { 6447 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6448 } 6449 if (constants != null && !constants.isEmpty()) { 6450 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6451 } 6452 6453 if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) { 6454 ModelBindingManager.setGlobalSchema(constants.get(0).toString()); 6455 } 6456 } 6457 } 6458 } 6459 6460 private void analyzeMssqlSetStmt(TMssqlSet stmt) { 6461 TExpression right = stmt.getVarExpr(); 6462 TObjectName columnObject = stmt.getVarName(); 6463 if (columnObject != null) { 6464 TableColumn tableColumn = null; 6465 Variable tableModel; 6466 if (columnObject.toString().indexOf(".") != -1) { 6467 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6468 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 6469 } else { 6470 tableModel = modelFactory.createVariable(columnObject); 6471 } 6472 tableModel.setCreateTable(true); 6473 tableModel.setSubType(SubType.record); 6474 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 6475 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 6476 } 6477 else { 6478 tableColumn = tableModel.getColumns().get(0); 6479 } 6480 6481 if (tableColumn != null && right!=null) { 6482 columnsInExpr visitor = new columnsInExpr(); 6483 right.inOrderTraverse(visitor); 6484 List<TObjectName> objectNames = visitor.getObjectNames(); 6485 List<TParseTreeNode> functions = visitor.getFunctions(); 6486 List<TParseTreeNode> constants = visitor.getConstants(); 6487 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6488 6489 if (functions != null && !functions.isEmpty()) { 6490 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6491 } 6492 if (subquerys != null && !subquerys.isEmpty()) { 6493 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6494 } 6495 if (objectNames != null && !objectNames.isEmpty()) { 6496 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6497 } 6498 if (constants != null && !constants.isEmpty()) { 6499 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6500 } 6501 6502 if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) { 6503 ModelBindingManager.setGlobalSchema(constants.get(0).toString()); 6504 } 6505 } 6506 else if(tableColumn!=null && stmt.getSubquery()!=null){ 6507 analyzeCustomSqlStmt(stmt.getSubquery()); 6508 analyzeSubqueryDataFlowRelation(tableColumn, Arrays.asList(stmt.getSubquery()), EffectType.select); 6509 } 6510 } 6511 } 6512 6513 private void analyzeAssignStmt(TAssignStmt stmt) { 6514 TExpression left = stmt.getLeft(); 6515 TExpression right = stmt.getExpression(); 6516 TObjectName columnObject = null; 6517 if (left == null) { 6518 columnObject = stmt.getVariableName(); 6519 } else if (left.getExpressionType() == EExpressionType.simple_object_name_t) { 6520 columnObject = left.getObjectOperand(); 6521 } 6522 if (columnObject != null) { 6523 TableColumn tableColumn = null; 6524 if (columnObject.getDbObjectType() == EDbObjectType.variable || stmt.getVariableName() != null) { 6525 Variable tableModel; 6526 if (columnObject.toString().indexOf(".") != -1) { 6527 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6528 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 6529 } else { 6530 tableModel = modelFactory.createVariable(columnObject); 6531 } 6532 tableModel.setCreateTable(true); 6533 tableModel.setSubType(SubType.record); 6534 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 6535 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 6536 } else { 6537 tableColumn = tableModel.getColumns().get(0); 6538 } 6539 } else { 6540 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6541 if (splits.size() > 1) { 6542 Table tableModel = modelManager 6543 .getTableByName(DlineageUtil.getTableFullName(splits.get(splits.size() - 2))); 6544 if (tableModel == null) { 6545 String procedureName = DlineageUtil.getProcedureParentName(stmt); 6546 String variableString = splits.get(splits.size() - 2).toString(); 6547 if (variableString.startsWith(":")) { 6548 variableString = variableString.substring(variableString.indexOf(":") + 1); 6549 } 6550 if (!SQLUtil.isEmpty(procedureName)) { 6551 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 6552 } 6553 tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 6554 } 6555 if (tableModel != null) { 6556 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 6557 } 6558 } 6559 } 6560 6561 if (tableColumn != null && right != null) { 6562 Transform transform = new Transform(); 6563 transform.setType(Transform.EXPRESSION); 6564 transform.setCode(right); 6565 tableColumn.setTransform(transform);; 6566 columnsInExpr visitor = new columnsInExpr(); 6567 right.inOrderTraverse(visitor); 6568 List<TObjectName> objectNames = visitor.getObjectNames(); 6569 List<TParseTreeNode> functions = visitor.getFunctions(); 6570 List<TParseTreeNode> constants = visitor.getConstants(); 6571 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6572 6573 if (functions != null && !functions.isEmpty()) { 6574 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6575 } 6576 if (subquerys != null && !subquerys.isEmpty()) { 6577 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6578 } 6579 if (objectNames != null && !objectNames.isEmpty()) { 6580 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6581 } 6582 if (constants != null && !constants.isEmpty()) { 6583 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6584 } 6585 } 6586 } 6587 } 6588 6589 private void analyzeOpenForStmt(TOpenforStmt stmt) { 6590 if (stmt.getSubquery() == null) { 6591 return; 6592 } 6593 6594 Variable cursorTempTable = modelFactory.createCursor(stmt); 6595 cursorTempTable.setVariable(true); 6596 cursorTempTable.setSubType(SubType.cursor); 6597 modelManager.bindCursorModel(stmt, cursorTempTable); 6598 analyzeSelectStmt(stmt.getSubquery()); 6599 6600 TableColumn cursorColumn = null; 6601 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 6602 TObjectName starColumn = new TObjectName(); 6603 starColumn.setString("*"); 6604 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6605 } else { 6606 cursorColumn = cursorTempTable.getColumns().get(0); 6607 } 6608 6609 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 6610 if (resultSetModel != null) { 6611 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6612 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6613 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6614 dataflowRelation.setEffectType(EffectType.cursor); 6615 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6616 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6617 } 6618 } 6619 } 6620 6621 private void analyzeCursorDeclStmt(TCursorDeclStmt stmt) { 6622 if (stmt.getSubquery() == null) { 6623 return; 6624 } 6625 6626 Variable cursorTempTable = modelFactory.createCursor(stmt); 6627 cursorTempTable.setVariable(true); 6628 cursorTempTable.setSubType(SubType.cursor); 6629 modelManager.bindCursorModel(stmt, cursorTempTable); 6630 analyzeSelectStmt(stmt.getSubquery()); 6631 6632 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 6633 if(resultSetModel!=null && resultSetModel.isDetermined()) { 6634 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6635 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6636 TObjectName columnName = new TObjectName(); 6637 columnName.setString(resultColumn.getName()); 6638 TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, columnName, true); 6639 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6640 dataflowRelation.setEffectType(EffectType.cursor); 6641 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6642 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6643 } 6644 } 6645 else { 6646 TableColumn cursorColumn = null; 6647 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 6648 TObjectName starColumn = new TObjectName(); 6649 starColumn.setString("*"); 6650 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6651 } else { 6652 cursorColumn = cursorTempTable.getColumns().get(0); 6653 } 6654 if (resultSetModel != null) { 6655 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6656 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6657 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6658 dataflowRelation.setEffectType(EffectType.cursor); 6659 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6660 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6661 } 6662 } 6663 } 6664 6665 } 6666 6667 private void analyzeDb2Declare(TDb2SqlVariableDeclaration stmt) { 6668 TDeclareVariableList variables = stmt.getVariables(); 6669 if (variables == null) { 6670 return; 6671 } 6672 for (int i = 0; i < variables.size(); i++) { 6673 TDeclareVariable variable = variables.getDeclareVariable(i); 6674 if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) { 6675 6676 6677 TObjectName tableName = variable.getVariableName(); 6678 TTableElementList columns = variable.getTableTypeDefinitions(); 6679 6680 Table tableModel = modelFactory.createTableByName(tableName, true); 6681 tableModel.setCreateTable(true); 6682 String procedureParent = getProcedureParentName(stmt); 6683 if (procedureParent != null) { 6684 tableModel.setParent(procedureParent); 6685 } 6686 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 6687 6688 for (int j = 0; j < columns.size(); j++) { 6689 TTableElement tableElement = columns.getTableElement(j); 6690 TColumnDefinition column = tableElement.getColumnDefinition(); 6691 if (column != null && column.getColumnName() != null) { 6692 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 6693 } 6694 } 6695 } else if (variable.getVariableName() != null) { 6696 Variable cursorVariable = modelFactory.createVariable(variable.getVariableName()); 6697 cursorVariable.setCreateTable(true); 6698 cursorVariable.setSubType(SubType.record); 6699 if(variable.getDatatype()!=null && isSimpleDataType(variable.getDatatype())){ 6700 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, 6701 variable.getVariableName(), true); 6702 } 6703 else { 6704 TObjectName variableProperties = new TObjectName(); 6705 variableProperties.setString("*"); 6706 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, 6707 variableProperties, true); 6708 } 6709 } 6710 } 6711 } 6712 6713 private void analyzeMssqlDeclare(TMssqlDeclare stmt) { 6714 if (stmt.getDeclareType() == EDeclareType.variable) { 6715 TDeclareVariableList variables = stmt.getVariables(); 6716 if (variables == null) { 6717 return; 6718 } 6719 for (int i = 0; i < variables.size(); i++) { 6720 TDeclareVariable variable = variables.getDeclareVariable(i); 6721 if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) { 6722 6723 6724 TObjectName tableName = variable.getVariableName(); 6725 TTableElementList columns = variable.getTableTypeDefinitions(); 6726 6727 Variable tableModel = modelFactory.createVariable(tableName); 6728 tableModel.setVariable(true); 6729 tableModel.setCreateTable(true); 6730 String procedureParent = getProcedureParentName(stmt); 6731 if (procedureParent != null) { 6732 tableModel.setParent(procedureParent); 6733 } 6734 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 6735 6736 for (int j = 0; j < columns.size(); j++) { 6737 TTableElement tableElement = columns.getTableElement(j); 6738 TColumnDefinition column = tableElement.getColumnDefinition(); 6739 if (column != null && column.getColumnName() != null) { 6740 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 6741 } 6742 } 6743 } else if (variable.getVariableName() != null) { 6744 Variable cursorVariable = modelFactory.createVariable(variable.getVariableName()); 6745 cursorVariable.setCreateTable(true); 6746 cursorVariable.setSubType(SubType.record); 6747 TableColumn variableProperty = null; 6748 if (variable.getDatatype() != null && isSimpleDataType(variable.getDatatype())) { 6749 variableProperty = modelFactory.createTableColumn(cursorVariable, variable.getVariableName(), 6750 true); 6751 } else { 6752 TObjectName variableProperties = new TObjectName(); 6753 variableProperties.setString("*"); 6754 variableProperty = modelFactory.createTableColumn(cursorVariable, variableProperties, true); 6755 } 6756 6757 if (variable.getDefaultValue() != null && variable.getDefaultValue().getSubQuery() != null) { 6758 analyzeSelectStmt(variable.getDefaultValue().getSubQuery()); 6759 ResultSet resultSetModel = (ResultSet) modelManager 6760 .getModel(variable.getDefaultValue().getSubQuery()); 6761 if (variableProperty != null && resultSetModel != null) { 6762 for (ResultColumn column : resultSetModel.getColumns()) { 6763 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6764 dataflowRelation.setEffectType(EffectType.select); 6765 dataflowRelation.addSource(new ResultColumnRelationshipElement(column)); 6766 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6767 } 6768 } 6769 } 6770 } 6771 } 6772 } else if (stmt.getDeclareType() == EDeclareType.cursor) { 6773 Variable cursorTempTable = modelFactory.createCursor(stmt); 6774 cursorTempTable.setVariable(true); 6775 cursorTempTable.setSubType(SubType.cursor); 6776 modelManager.bindCursorModel(stmt, cursorTempTable); 6777 analyzeSelectStmt(stmt.getSubquery()); 6778 ResultSet resultSetModel = (ResultSet)modelManager.getModel(stmt.getSubquery()); 6779 if (resultSetModel != null && resultSetModel.isDetermined()) { 6780 for(ResultColumn resultColumn: resultSetModel.getColumns()){ 6781 TObjectName starColumn = new TObjectName(); 6782 starColumn.setString(resultColumn.getName()); 6783 TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6784 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6785 dataflowRelation.setEffectType(EffectType.cursor); 6786 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6787 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6788 } 6789 } 6790 else { 6791 TableColumn cursorColumn = null; 6792 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 6793 TObjectName starColumn = new TObjectName(); 6794 starColumn.setString("*"); 6795 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6796 cursorColumn.setShowStar(false); 6797 cursorColumn.setExpandStar(true); 6798 } else { 6799 cursorColumn = cursorTempTable.getColumns().get(0); 6800 } 6801 6802 if (resultSetModel != null) { 6803 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6804 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6805 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6806 dataflowRelation.setEffectType(EffectType.cursor); 6807 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6808 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6809 } 6810 } 6811 } 6812 } 6813 } 6814 6815 6816 private boolean analyzeMssqlJsonDeclare(TMssqlDeclare stmt, String jsonName, Table jsonTable) { 6817 TDeclareVariableList variables = stmt.getVariables(); 6818 if (variables == null) { 6819 return false; 6820 } 6821 for (int i = 0; i < variables.size(); i++) { 6822 TDeclareVariable variable = variables.getDeclareVariable(i); 6823 TObjectName variableName = variable.getVariableName(); 6824 if (DlineageUtil.getIdentifierNormalTableName(variableName.toString()) 6825 .equals(DlineageUtil.getIdentifierNormalTableName(jsonName))) { 6826 if (variable.getDefaultValue() != null) { 6827 Table variableTable = modelFactory.createJsonVariable(variableName); 6828 variableTable.setVariable(true); 6829 variableTable.setSubType(SubType.scalar); 6830 variableTable.setCreateTable(true); 6831 TableColumn property = modelFactory.createVariableProperty(variableTable, variable); 6832 6833 for (int j = 0; j < jsonTable.getColumns().size(); j++) { 6834 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 6835 relation.setEffectType(EffectType.select); 6836 relation.setTarget(new TableColumnRelationshipElement(jsonTable.getColumns().get(j))); 6837 relation.addSource(new TableColumnRelationshipElement(property)); 6838 } 6839 } 6840 return true; 6841 } 6842 } 6843 return false; 6844 } 6845 6846 private void analyzeCreateTableStmt(TCreateTableSqlStatement stmt) { 6847 if (stmt.getCloneSourceTable() != null) { 6848 analyzeCloneTableStmt(stmt); 6849 return; 6850 } 6851 6852 TTable table = stmt.getTargetTable(); 6853 6854 boolean hasDefinition = false; 6855 6856 if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) { 6857 hasDefinition = true; 6858 } 6859 6860 if (table != null) { 6861 Table tableModel = modelFactory.createTableFromCreateDDL(table, hasDefinition || (stmt.getSubQuery() == null && hasDefinition) 6862 || (stmt.getSubQuery()!=null && stmt.getSubQuery().getSetOperatorType() == ESetOperatorType.none && stmt.getSubQuery().getResultColumnList().toString().indexOf("*") == -1)); 6863 if (stmt.isExternal()) { 6864 tableModel.setExternal(true); 6865 } 6866 6867 if (stmt.getSubQuery() != null) { 6868 Process process = modelFactory.createProcess(stmt); 6869 tableModel.addProcess(process); 6870 } 6871 6872 String procedureParent = getProcedureParentName(stmt); 6873 if (procedureParent != null) { 6874 tableModel.setParent(procedureParent); 6875 } 6876 6877 if (stmt.isUsingTemplate()) { 6878 // Snowflake CREATE TABLE ... USING TEMPLATE <query>: the query only 6879 // infers the column definitions (e.g. ARRAY_AGG(OBJECT_CONSTRUCT(*)) 6880 // over INFER_SCHEMA); it does NOT populate the table. Analyze it so its 6881 // own sources (the stage / INFER_SCHEMA) still resolve, but do not 6882 // project its result columns onto the target table or emit CTAS-style 6883 // data-flow edges that would misrepresent it as data population. 6884 if (stmt.getSubQuery() != null) { 6885 analyzeSelectStmt(stmt.getSubQuery()); 6886 } 6887 return; 6888 } 6889 6890 if (hasDefinition) { 6891 if(stmt.getSubQuery()!=null) { 6892 TSelectSqlStatement subquery = stmt.getSubQuery(); 6893 analyzeSelectStmt(subquery); 6894 Process process = modelFactory.createProcess(stmt); 6895 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 6896 if(resultSetModel.isDetermined()){ 6897 tableModel.setFromDDL(true); 6898 } 6899 if (resultSetModel != null) { 6900 int resultSetSize = resultSetModel.getColumns().size(); 6901 int stmtColumnSize = stmt.getColumnList().size(); 6902 int j = 0; 6903 int tableColumnSize = stmtColumnSize; 6904 if (resultSetModel.isDetermined() && resultSetSize > tableColumnSize) { 6905 tableColumnSize = resultSetSize; 6906 } 6907 for (int i = 0; i < tableColumnSize && j < resultSetSize; i++) { 6908 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 6909 if (i < stmtColumnSize) { 6910 TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName(); 6911 6912 if (!resultSetModel.getColumns().get(j).getName().contains("*")) { 6913 j++; 6914 } else { 6915 if (resultSetSize - j == stmt.getColumnList().size() - i) { 6916 j++; 6917 } 6918 } 6919 6920 if (alias != null) { 6921 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true); 6922 if (resultColumn != null) { 6923 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 6924 relation.setEffectType(EffectType.create_table); 6925 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 6926 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6927 relation.setProcess(process); 6928 } 6929 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 6930 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, 6931 (TObjectName) resultColumn.getColumnObject(), true); 6932 if (resultColumn != null) { 6933 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 6934 relation.setEffectType(EffectType.create_table); 6935 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 6936 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6937 relation.setProcess(process); 6938 } 6939 } else if (resultColumn.getColumnObject() instanceof TResultColumn) { 6940 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, 6941 ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), true); 6942 ResultColumn column = (ResultColumn) modelManager 6943 .getModel(resultColumn.getColumnObject()); 6944 if (column != null && !column.getStarLinkColumns().isEmpty()) { 6945 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 6946 } 6947 if (resultColumn != null) { 6948 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 6949 relation.setEffectType(EffectType.create_table); 6950 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 6951 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6952 relation.setProcess(process); 6953 } 6954 } 6955 } 6956 else if(resultSetModel.isDetermined()){ 6957 TObjectName tableName = new TObjectName(); 6958 tableName.setString(resultColumn.getName()); 6959 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, tableName, true); 6960 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 6961 relation.setEffectType(EffectType.create_table); 6962 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 6963 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6964 relation.setProcess(process); 6965 j++; 6966 } 6967 } 6968 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 6969 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 6970 impactRelation.setEffectType(EffectType.create_table); 6971 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 6972 resultSetModel.getRelationRows())); 6973 impactRelation.setTarget( 6974 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 6975 } 6976 } 6977 6978 if (subquery.getResultColumnList() == null && subquery.getValueClause() != null 6979 && subquery.getValueClause().getValueRows().size() == stmt.getColumnList().size()) { 6980 for (int i = 0; i < stmt.getColumnList().size(); i++) { 6981 TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName(); 6982 6983 if (alias != null) { 6984 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true); 6985 6986 TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr(); 6987 6988 columnsInExpr visitor = new columnsInExpr(); 6989 expression.inOrderTraverse(visitor); 6990 List<TObjectName> objectNames = visitor.getObjectNames(); 6991 List<TParseTreeNode> functions = visitor.getFunctions(); 6992 6993 if (functions != null && !functions.isEmpty()) { 6994 analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select); 6995 6996 } 6997 6998 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6999 if (subquerys != null && !subquerys.isEmpty()) { 7000 analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select); 7001 } 7002 7003 analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions); 7004 List<TParseTreeNode> constants = visitor.getConstants(); 7005 analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions); 7006 } 7007 } 7008 } 7009 7010 return; 7011 } 7012 else { 7013 for (int i = 0; i < stmt.getColumnList().size(); i++) { 7014 TColumnDefinition column = stmt.getColumnList().getColumn(i); 7015 if (column.getDatatype() != null && column.getDatatype().getTypeOfList() != null 7016 && column.getDatatype().getTypeOfList().getColumnDefList() != null) { 7017 for (int j = 0; j < column.getDatatype().getTypeOfList().getColumnDefList().size(); j++) { 7018 TObjectName columnName = new TObjectName(); 7019 if (column.getDatatype().getDataType() == EDataType.array_t) { 7020// columnName.setString(column.getColumnName().getColumnNameOnly() + ".array." 7021// + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j) 7022// .getColumnName().getColumnNameOnly()); 7023 columnName.setString(column.getColumnName().getColumnNameOnly() + "." 7024 + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j) 7025 .getColumnName().getColumnNameOnly()); 7026 } else { 7027 columnName.setString(column.getColumnName().getColumnNameOnly() + "." 7028 + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j) 7029 .getColumnName().getColumnNameOnly()); 7030 } 7031 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName, 7032 hasDefinition); 7033 tableColumn.setStruct(true); 7034 tableColumn.setColumnIndex(i); 7035 appendTableColumnToSQLEnv(tableModel, tableColumn); 7036 7037 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 7038 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 7039 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 7040 crudRelationship.setEffectType(EffectType.create_table); 7041 } 7042 } 7043 continue; 7044 } 7045 if (column.getDatatype() != null && column.getDatatype().getColumnDefList() != null) { 7046 Stack<TColumnDefinition> columnPaths = new Stack<TColumnDefinition>(); 7047 flattenStructColumns(hasDefinition, tableModel, column, columnPaths, i); 7048 continue; 7049 } 7050 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column.getColumnName(), 7051 hasDefinition); 7052 if (tableColumn == null) { 7053 continue; 7054 } 7055 7056 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 7057 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 7058 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 7059 crudRelationship.setEffectType(EffectType.create_table); 7060 } 7061 7062 if (column.getDatatype() != null && column.getDatatype().getDataType() == EDataType.variant_t) { 7063 if (tableColumn != null) { 7064 tableColumn.setVariant(true); 7065 } 7066 } 7067 if (column.getDatatype() != null) { 7068 String dType = column.getDatatype().getDataTypeName(); 7069 if ((!SQLUtil.isEmpty(dType)) && (dType.indexOf("_") > 0)) { 7070 dType = dType.split("_")[0]; 7071 } 7072 tableColumn.setDataType(dType); 7073 } 7074 appendTableColumnToSQLEnv(tableModel, tableColumn); 7075 } 7076 } 7077 } 7078 7079 if (stmt.getExternalTableOption("DATA_SOURCE") != null) { 7080 String dataSourceName = stmt.getExternalTableOption("DATA_SOURCE"); 7081 Table dataSource = modelManager.getTableByName(DlineageUtil.getTableFullName(dataSourceName)); 7082 if (dataSource != null) { 7083 TableColumn dataSourceColumn = dataSource.getColumns().get(0); 7084 for (int i = 0; i < tableModel.getColumns().size(); i++) { 7085 TableColumn column = tableModel.getColumns().get(i); 7086 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7087 relation.setTarget(new TableColumnRelationshipElement(column)); 7088 relation.addSource(new TableColumnRelationshipElement(dataSourceColumn)); 7089 7090 appendTableColumnToSQLEnv(tableModel, column); 7091 } 7092 } 7093 } 7094 7095 if (stmt.getSubQuery() != null) { 7096 7097 analyzeSelectStmt(stmt.getSubQuery()); 7098 7099 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 7100 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 7101 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 7102 impactRelation.setEffectType(EffectType.create_table); 7103 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 7104 resultSetModel.getRelationRows())); 7105 impactRelation.setTarget( 7106 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 7107 } 7108 } 7109 7110 if (stmt.getSubQuery() != null && !stmt.getSubQuery().isCombinedQuery()) { 7111 SelectResultSet resultSetModel = (SelectResultSet) modelManager 7112 .getModel(stmt.getSubQuery().getResultColumnList()); 7113 if(resultSetModel.isDetermined()){ 7114 tableModel.setDetermined(true); 7115 tableModel.setFromDDL(true); 7116 } 7117 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7118 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7119 if (resultSetModel.isDetermined() && resultColumn.getName().endsWith("*")) { 7120 continue; 7121 } 7122 7123 if (resultColumn.getColumnObject() instanceof TResultColumn) { 7124 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 7125 7126 TAliasClause alias = columnObject.getAliasClause(); 7127 if (alias != null && alias.getAliasName() != null) { 7128 TableColumn tableColumn = null; 7129 if (!hasDefinition) { 7130 tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(), 7131 !hasDefinition); 7132 } else { 7133 tableColumn = tableModel.getColumns().get(i); 7134 } 7135 7136 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7137 appendTableColumnToSQLEnv(tableModel, tableColumn); 7138 } 7139 7140 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7141 relation.setEffectType(EffectType.create_table); 7142 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7143 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7144 Process process = modelFactory.createProcess(stmt); 7145 relation.setProcess(process); 7146 } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) { 7147 TableColumn tableColumn = null; 7148 TObjectName columnObj = columnObject.getFieldAttr(); 7149 if(columnObj == null) { 7150 columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand(); 7151 } 7152 if ((columnObj == null || columnObj.toString().endsWith("*")) && !resultColumn.getName().endsWith("*")) { 7153 columnObj = new TObjectName(); 7154 columnObj.setString(resultColumn.getName()); 7155 } 7156 7157 if(columnObj == null){ 7158 logger.info("Can't handle column " + resultColumn.getName()); 7159 continue; 7160 } 7161 7162 if (!hasDefinition) { 7163 tableColumn = modelFactory.createTableColumn(tableModel, columnObj, 7164 !hasDefinition); 7165 if (tableColumn == null) { 7166 if (tableModel.getColumns().isEmpty()) { 7167 logger.info("Add table " + tableModel.getName() + " column " + columnObj.toString() + " failed"); 7168 } 7169 else if (resultColumn.getName().endsWith("*")) { 7170 for (int j = 0; j < tableModel.getColumns().size(); j++) { 7171 tableColumn = tableModel.getColumns().get(j); 7172 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7173 relation.setEffectType(EffectType.create_table); 7174 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7175 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7176 if (tableColumn.getName().endsWith("*") 7177 && resultColumn.getName().endsWith("*")) { 7178 tableModel.setStarStmt("create_table"); 7179 } 7180 Process process = modelFactory.createProcess(stmt); 7181 relation.setProcess(process); 7182 } 7183 } 7184 continue; 7185 } 7186 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7187 appendTableColumnToSQLEnv(tableModel, tableColumn); 7188 } 7189 7190 Object model = modelManager 7191 .getModel(resultColumn.getColumnObject()); 7192 if (model instanceof ResultColumn) { 7193 ResultColumn column = (ResultColumn) model; 7194 if (tableColumn.getName().endsWith("*") && column != null 7195 && !column.getStarLinkColumns().isEmpty()) { 7196 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7197 } 7198 7199 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7200 relation.setEffectType(EffectType.create_table); 7201 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7202 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7203 if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) { 7204 tableModel.setStarStmt("create_table"); 7205 } 7206 Process process = modelFactory.createProcess(stmt); 7207 relation.setProcess(process); 7208 } 7209 else if(model instanceof LinkedHashMap) { 7210 String columnName = getColumnNameOnly(resultColumn.getName()); 7211 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 7212 if (columnObj.toString().endsWith("*")) { 7213 for (String key : resultColumns.keySet()) { 7214 tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName()); 7215 DataFlowRelationship relation = modelFactory 7216 .createDataFlowRelation(); 7217 relation.setEffectType(EffectType.create_table); 7218 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7219 relation.addSource( 7220 new ResultColumnRelationshipElement(resultColumns.get(key))); 7221 Process process = modelFactory.createProcess(stmt); 7222 relation.setProcess(process); 7223 } 7224 } else if (resultColumns.containsKey(columnName)) { 7225 ResultColumn column = resultColumns.get(columnName); 7226 tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName()); 7227 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7228 relation.setEffectType(EffectType.create_table); 7229 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7230 relation.addSource(new ResultColumnRelationshipElement(column)); 7231 Process process = modelFactory.createProcess(stmt); 7232 relation.setProcess(process); 7233 } 7234 } 7235 } else { 7236 if (resultColumn.getName().endsWith("*")) { 7237 for (int j = 0; j < tableModel.getColumns().size(); j++) { 7238 tableColumn = tableModel.getColumns().get(j); 7239 ResultColumn column = (ResultColumn) modelManager 7240 .getModel(resultColumn.getColumnObject()); 7241 if (tableColumn.getName().endsWith("*") && column != null 7242 && !column.getStarLinkColumns().isEmpty()) { 7243 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7244 } 7245 7246 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7247 relation.setEffectType(EffectType.create_table); 7248 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7249 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7250 if (tableColumn.getName().endsWith("*") 7251 && resultColumn.getName().endsWith("*")) { 7252 tableModel.setStarStmt("create_table"); 7253 ; 7254 } 7255 Process process = modelFactory.createProcess(stmt); 7256 relation.setProcess(process); 7257 } 7258 } else { 7259 tableColumn = tableModel.getColumns().get(i); 7260 Object model = modelManager 7261 .getModel(resultColumn.getColumnObject()); 7262 String columnName = getColumnNameOnly(resultColumn.getName()); 7263 if(model instanceof LinkedHashMap) { 7264 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 7265 if (resultColumns.size() == tableModel.getColumns().size()) { 7266 int j = 0; 7267 for (String key : resultColumns.keySet()) { 7268 if (j == i) { 7269 ResultColumn column = resultColumns.get(key); 7270 DataFlowRelationship relation = modelFactory 7271 .createDataFlowRelation(); 7272 relation.setEffectType(EffectType.create_table); 7273 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7274 relation.addSource(new ResultColumnRelationshipElement(column)); 7275 Process process = modelFactory.createProcess(stmt); 7276 relation.setProcess(process); 7277 } 7278 j++; 7279 } 7280 } else if (resultColumns.containsKey(columnName)) { 7281 ResultColumn column = resultColumns.get(columnName); 7282 tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName()); 7283 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7284 relation.setEffectType(EffectType.create_table); 7285 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7286 relation.addSource(new ResultColumnRelationshipElement(column)); 7287 Process process = modelFactory.createProcess(stmt); 7288 relation.setProcess(process); 7289 } else { 7290 throw new UnsupportedOperationException("Can't handle this star case."); 7291 } 7292 } 7293 else if (model instanceof ResultColumn) { 7294 ResultColumn column = (ResultColumn) modelManager 7295 .getModel(resultColumn.getColumnObject()); 7296 if (tableColumn.getName().endsWith("*") && column != null 7297 && !column.getStarLinkColumns().isEmpty()) { 7298 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7299 } 7300 7301 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7302 relation.setEffectType(EffectType.create_table); 7303 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7304 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7305 if (tableColumn.getName().endsWith("*") 7306 && resultColumn.getName().endsWith("*")) { 7307 tableModel.setStarStmt("create_table"); 7308 } 7309 Process process = modelFactory.createProcess(stmt); 7310 relation.setProcess(process); 7311 } 7312 } 7313 } 7314 } else { 7315 TableColumn tableColumn = null; 7316 if (!hasDefinition) { 7317 TObjectName columnName = new TObjectName(); 7318 columnName.setString(resultColumn.getColumnObject().toString()); 7319 tableColumn = modelFactory.createTableColumn(tableModel, columnName, !hasDefinition); 7320 if(tableColumn == null){ 7321 continue; 7322 } 7323 } else { 7324 tableColumn = tableModel.getColumns().get(i); 7325 } 7326 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 7327 if (column != null && !column.getStarLinkColumns().isEmpty()) { 7328 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7329 } 7330 7331 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7332 appendTableColumnToSQLEnv(tableModel, tableColumn); 7333 } 7334 7335 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7336 relation.setEffectType(EffectType.create_table); 7337 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7338 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7339 Process process = modelFactory.createProcess(stmt); 7340 relation.setProcess(process); 7341 } 7342 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 7343 TableColumn tableColumn = null; 7344 if (!hasDefinition) { 7345 tableColumn = modelFactory.createTableColumn(tableModel, 7346 (TObjectName) resultColumn.getColumnObject(), !hasDefinition); 7347 } else { 7348 tableColumn = tableModel.getColumns().get(i); 7349 } 7350 7351 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7352 appendTableColumnToSQLEnv(tableModel, tableColumn); 7353 } 7354 7355 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7356 relation.setEffectType(EffectType.create_table); 7357 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7358 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7359 Process process = modelFactory.createProcess(stmt); 7360 relation.setProcess(process); 7361 } 7362 } 7363 } else if (stmt.getSubQuery() != null) { 7364 SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(stmt.getSubQuery()); 7365 if(resultSetModel.isDetermined()){ 7366 tableModel.setDetermined(true); 7367 tableModel.setFromDDL(true); 7368 } 7369 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7370 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7371 if (resultColumn.getColumnObject() instanceof TResultColumn) { 7372 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 7373 7374 TAliasClause alias = columnObject.getAliasClause(); 7375 if (alias != null && alias.getAliasName() != null) { 7376 TableColumn tableColumn = null; 7377 if (!hasDefinition) { 7378 tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(), 7379 !hasDefinition); 7380 if (tableColumn == null) { 7381 continue; 7382 } 7383 } else { 7384 tableColumn = tableModel.getColumns().get(i); 7385 } 7386 7387 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7388 appendTableColumnToSQLEnv(tableModel, tableColumn); 7389 } 7390 7391 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7392 relation.setEffectType(EffectType.create_table); 7393 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7394 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7395 Process process = modelFactory.createProcess(stmt); 7396 relation.setProcess(process); 7397 } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) { 7398 TableColumn tableColumn = null; 7399 TObjectName columnObj = columnObject.getFieldAttr(); 7400 if(columnObj == null) { 7401 columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand(); 7402 } 7403 if (!hasDefinition) { 7404 tableColumn = modelFactory.createTableColumn(tableModel, columnObj, 7405 !hasDefinition); 7406 if (tableColumn == null) { 7407 continue; 7408 } 7409 } else { 7410 tableColumn = tableModel.getColumns().get(i); 7411 } 7412 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 7413 if (column != null && !column.getStarLinkColumns().isEmpty()) { 7414 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7415 } 7416 7417 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7418 appendTableColumnToSQLEnv(tableModel, tableColumn); 7419 } 7420 7421 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7422 relation.setEffectType(EffectType.create_table); 7423 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7424 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7425 Process process = modelFactory.createProcess(stmt); 7426 relation.setProcess(process); 7427 } else { 7428 ErrorInfo errorInfo = new ErrorInfo(); 7429 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 7430 errorInfo.setErrorMessage("Can't handle the table column " + columnObject.toString()); 7431 errorInfo.setStartPosition(new Pair3<Long, Long, String>( 7432 columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo, 7433 ModelBindingManager.getGlobalHash())); 7434 errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo, 7435 columnObject.getEndToken().columnNo + columnObject.getEndToken().getAstext().length(), 7436 ModelBindingManager.getGlobalHash())); 7437 errorInfos.add(errorInfo); 7438 continue; 7439 } 7440 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 7441 TableColumn tableColumn = null; 7442 if (!hasDefinition) { 7443 tableColumn = modelFactory.createTableColumn(tableModel, 7444 (TObjectName) resultColumn.getColumnObject(), !hasDefinition); 7445 } else { 7446 tableColumn = tableModel.getColumns().get(i); 7447 } 7448 7449 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7450 appendTableColumnToSQLEnv(tableModel, tableColumn); 7451 } 7452 7453 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7454 relation.setEffectType(EffectType.create_table); 7455 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7456 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7457 Process process = modelFactory.createProcess(stmt); 7458 relation.setProcess(process); 7459 } 7460 } 7461 } else if (stmt.getLikeTableName() != null) { 7462 Table likeTableModel = modelFactory.createTableByName(stmt.getLikeTableName()); 7463 7464 if(likeTableModel.isCreateTable()){ 7465 for(TableColumn column: likeTableModel.getColumns()){ 7466 TObjectName tableColumn = new TObjectName(); 7467 tableColumn.setString(column.getName()); 7468 TableColumn createTableColumn = modelFactory.createTableColumn(tableModel, tableColumn, true); 7469 createTableColumn.setPrimaryKey(column.getPrimaryKey()); 7470 createTableColumn.setForeignKey(column.getForeignKey()); 7471 createTableColumn.setIndexKey(column.getIndexKey()); 7472 createTableColumn.setUnqiueKey(column.getUnqiueKey()); 7473 createTableColumn.setDataType(column.getDataType()); 7474 } 7475 tableModel.setCreateTable(true); 7476 } 7477 7478// Process process = modelFactory.createProcess(stmt); 7479// process.setType("Like Table"); 7480// tableModel.addProcess(process); 7481// 7482// 7483// DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7484// relation.setEffectType(EffectType.like_table); 7485// relation.setTarget( 7486// new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 7487// relation.addSource( 7488// new RelationRowsRelationshipElement<TableRelationRows>(likeTableModel.getRelationRows())); 7489// relation.setProcess(process); 7490 } 7491 7492 if (stmt.getStageLocation() != null && stmt.getStageLocation().getStageName() != null) { 7493 tableModel 7494 .setLocation(DlineageUtil.getTableFullName(stmt.getStageLocation().getStageName().toString())); 7495 Process process = modelFactory.createProcess(stmt); 7496 process.setType("Create External Table"); 7497 tableModel.addProcess(process); 7498 Table stage = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getLocation())); 7499 if (stage == null) { 7500 stage = modelManager.getTableByName( 7501 DlineageUtil.getTableFullName(stmt.getStageLocation().toString().replaceFirst("@", ""))); 7502 } 7503 if (stage == null) { 7504 stage = modelFactory.createTableByName(stmt.getStageLocation().toString().replaceFirst("@", ""), 7505 false); 7506 stage.setCreateTable(false); 7507 stage.setStage(true); 7508 if (stmt.getStageLocation().getPath() != null) { 7509 stage.setLocation(stmt.getStageLocation().getPath().toString()); 7510 TObjectName location = new TObjectName(); 7511 location.setString(stmt.getStageLocation().getPath().toString()); 7512 modelFactory.createStageLocation(stage, location); 7513 } else if (stmt.getRegex_pattern() != null) { 7514 stage.setLocation(stmt.getRegex_pattern()); 7515 TObjectName location = new TObjectName(); 7516 location.setString(stmt.getRegex_pattern()); 7517 modelFactory.createStageLocation(stage, location); 7518 } else { 7519 stage.setLocation("unknownPath"); 7520 TObjectName location = new TObjectName(); 7521 location.setString("unknownPath"); 7522 modelFactory.createStageLocation(stage, location); 7523 } 7524 } 7525 if (stage != null && !stage.getColumns().isEmpty()) { 7526 if (!tableModel.getColumns().isEmpty()) { 7527 for (int i = 0; i < tableModel.getColumns().size(); i++) { 7528 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7529 relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0))); 7530 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(i))); 7531 relation.setProcess(process); 7532 } 7533 } else { 7534 TObjectName starColumn = new TObjectName(); 7535 starColumn.setString("*"); 7536 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 7537 tableColumn.setExpandStar(false); 7538 tableColumn.setShowStar(true); 7539 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7540 relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0))); 7541 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7542 relation.setProcess(process); 7543 } 7544 } 7545 } else if (stmt.getTableOptions() != null && !stmt.getTableOptions().isEmpty()) { 7546 for (int i = 0; i < stmt.getTableOptions().size(); i++) { 7547 TCreateTableOption createTableOption = stmt.getTableOptions().get(i); 7548 if (createTableOption.getCreateTableOptionType() != ECreateTableOption.etoBigQueryExternal) 7549 continue; 7550 List<String> uris = createTableOption.getUris(); 7551 if (uris == null || uris.isEmpty()) 7552 continue; 7553 Process process = modelFactory.createProcess(stmt); 7554 process.setType("Create External Table"); 7555 tableModel.addProcess(process); 7556 if (tableModel.getColumns().isEmpty()) { 7557 TObjectName starColumn = new TObjectName(); 7558 starColumn.setString("*"); 7559 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 7560 tableColumn.setExpandStar(false); 7561 tableColumn.setShowStar(true); 7562 } 7563 for (String uri : uris) { 7564 Table uriFile = modelFactory.createTableByName(uri, true); 7565 uriFile.setPath(true); 7566 uriFile.setFileFormat(createTableOption.getFormat()); 7567 for (int j = 0; j < tableModel.getColumns().size(); j++) { 7568 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7569 if (stmt.getColumnList() != null) { 7570 TObjectName fileUri = new TObjectName(); 7571 fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString()); 7572 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 7573 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 7574 } else { 7575 TObjectName fileUri = new TObjectName(); 7576 fileUri.setString("*"); 7577 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 7578 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 7579 } 7580 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j))); 7581 relation.setProcess(process); 7582 } 7583 if (tableModel.getColumns().isEmpty()) { 7584 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7585 TObjectName fileUri = new TObjectName(); 7586 fileUri.setString("*"); 7587 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 7588 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 7589 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 7590 tableModel.getRelationRows())); 7591 relation.setProcess(process); 7592 } 7593 } 7594 } 7595 } else if (stmt.getSubQuery() == null && stmt.getTableLocation() != null) { 7596 Process process = modelFactory.createProcess(stmt); 7597 process.setType("Create External Table"); 7598 tableModel.addProcess(process); 7599 Table uriFile = modelFactory.createTableByName(stmt.getTableLocation(), true); 7600 uriFile.setPath(true); 7601 for (int j = 0; j < tableModel.getColumns().size(); j++) { 7602 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7603 if (stmt.getColumnList() != null) { 7604 TObjectName fileUri = new TObjectName(); 7605 fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString()); 7606 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 7607 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 7608 } else { 7609 TObjectName fileUri = new TObjectName(); 7610 fileUri.setString("*"); 7611 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 7612 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 7613 } 7614 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j))); 7615 relation.setProcess(process); 7616 } 7617 } 7618 7619 if (stmt.getTableConstraints() != null && stmt.getTableConstraints().size() > 0) { 7620 for (int i = 0; i < stmt.getTableConstraints().size(); i++) { 7621 TConstraint createTableConstraint = stmt.getTableConstraints().getConstraint(i); 7622 TPTNodeList<TColumnWithSortOrder> keyNames = createTableConstraint.getColumnList(); 7623 if (keyNames != null) { 7624 for (int k = 0; k < keyNames.size(); k++) { 7625 TObjectName keyName = keyNames.getElement(k).getColumnName(); 7626 // Skip functional indexes (expression-based indexes) where columnName is null 7627 if (keyName == null) { 7628 continue; 7629 } 7630 TObjectName referencedTableName = createTableConstraint.getReferencedObject(); 7631 TObjectNameList referencedTableColumns = createTableConstraint.getReferencedColumnList(); 7632 7633 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 7634 if (createTableConstraint.getConstraint_type() == EConstraintType.primary_key) { 7635 tableConstraint.setPrimaryKey(true); 7636 } else if (createTableConstraint.getConstraint_type() == EConstraintType.table_index) { 7637 tableConstraint.setIndexKey(true); 7638 } else if (createTableConstraint.getConstraint_type() == EConstraintType.unique) { 7639 tableConstraint.setUnqiueKey(true); 7640 } else if (createTableConstraint.getConstraint_type() == EConstraintType.foreign_key) { 7641 tableConstraint.setForeignKey(true); 7642 Table referencedTable = modelManager 7643 .getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 7644 if (referencedTable == null) { 7645 referencedTable = modelFactory.createTableByName(referencedTableName); 7646 } 7647 7648 if (referencedTableColumns != null) { 7649 for (int j = 0; j < referencedTableColumns.size(); j++) { 7650 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 7651 referencedTableColumns.getObjectName(j), false); 7652 if (tableColumn != null) { 7653 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7654 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 7655 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 7656 relation.setEffectType(EffectType.foreign_key); 7657 Process process = modelFactory.createProcess(stmt); 7658 relation.setProcess(process); 7659 if (this.option.isShowERDiagram()) { 7660 ERRelationship erRelation = modelFactory.createERRelation(); 7661 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 7662 erRelation 7663 .setTarget(new TableColumnRelationshipElement(tableConstraint)); 7664 } 7665 } 7666 } 7667 } 7668 } 7669 } 7670 } 7671 } 7672 } 7673 7674 if (stmt.getHiveTablePartition() != null && stmt.getHiveTablePartition().getColumnDefList() != null) { 7675 for (int i = 0; i < stmt.getHiveTablePartition().getColumnDefList().size(); i++) { 7676 TColumnDefinition column = stmt.getHiveTablePartition().getColumnDefList().getColumn(i); 7677 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 7678 appendTableColumnToSQLEnv(tableModel, column.getColumnName()); 7679 } 7680 } 7681 7682 } else { 7683 ErrorInfo errorInfo = new ErrorInfo(); 7684 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 7685 errorInfo.setErrorMessage("Can't get target table. CreateTableSqlStatement is " + stmt.toString()); 7686 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 7687 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 7688 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 7689 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 7690 ModelBindingManager.getGlobalHash())); 7691 errorInfos.add(errorInfo); 7692 } 7693 } 7694 7695 protected void flattenStructColumns(boolean hasDefinition, Table tableModel, TColumnDefinition column, 7696 Stack<TColumnDefinition> columnPaths, int index) { 7697 columnPaths.push(column); 7698 for (int j = 0; j < column.getDatatype().getColumnDefList().size(); j++) { 7699 TColumnDefinition columnDefinition = column.getDatatype().getColumnDefList().getColumn(j); 7700 if (columnDefinition.getDatatype().getColumnDefList() != null) { 7701 flattenStructColumns(hasDefinition, tableModel, columnDefinition, columnPaths, index); 7702 } else { 7703 TObjectName columnName = new TObjectName(); 7704 columnName.setString(getColumnName(columnPaths, columnDefinition)); 7705 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName, hasDefinition); 7706 tableColumn.setColumnIndex(index); 7707 tableColumn.setStruct(true); 7708 7709 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 7710 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 7711 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 7712 crudRelationship.setEffectType(EffectType.create_table); 7713 } 7714 7715 appendTableColumnToSQLEnv(tableModel, tableColumn); 7716 } 7717 } 7718 columnPaths.pop(); 7719 } 7720 7721 private String getColumnName(Stack<TColumnDefinition> columnPaths, TColumnDefinition column) { 7722 StringBuilder buffer = new StringBuilder(); 7723 Iterator<TColumnDefinition> iter = columnPaths.iterator(); 7724 while(iter.hasNext()) { 7725 buffer.append(iter.next().getColumnName().getColumnNameOnly()).append("."); 7726 } 7727 buffer.append(column.getColumnName().getColumnNameOnly()); 7728 return buffer.toString(); 7729 } 7730 7731 private void appendTableColumnToSQLEnv(Table tableModel, TableColumn tableColumn) { 7732 //tableModel如果非determined,请不要添加到sqlenv里 7733 if (sqlenv != null && tableColumn!=null) { 7734 TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true); 7735 if (schema != null) { 7736 TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 7737 if (tableColumn.hasStarLinkColumn()) { 7738 for (String column : tableColumn.getStarLinkColumnNames()) { 7739 tempTable.addColumn(DlineageUtil.getColumnNameOnly(column)); 7740 } 7741 } else { 7742 tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getName())); 7743 } 7744 } 7745 } 7746 } 7747 7748 private void appendTableColumnToSQLEnv(Table tableModel, TObjectName tableColumn) { 7749 if (sqlenv != null) { 7750 TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true); 7751 if (schema != null) { 7752 TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 7753 tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getColumnNameOnly())); 7754 } 7755 } 7756 } 7757 7758 private void analyzeCreateStageStmt(TCreateStageStmt stmt) { 7759 TObjectName stageName = stmt.getStageName(); 7760 7761 if (stageName != null) { 7762 7763 Table tableModel = modelFactory.createStage(stageName); 7764 tableModel.setCreateTable(true); 7765 tableModel.setStage(true); 7766 tableModel.setLocation(stmt.getExternalStageURL()); 7767 7768 Process process = modelFactory.createProcess(stmt); 7769 tableModel.addProcess(process); 7770 7771 TableColumn locationColumn = null; 7772 if (stmt.getExternalStageURL() != null) { 7773 TObjectName location = new TObjectName(); 7774 location.setString(stmt.getExternalStageURL()); 7775 locationColumn = modelFactory.createStageLocation(tableModel, location); 7776 7777 Table pathModel = modelFactory.createTableByName(stmt.getExternalStageURL(), true); 7778 pathModel.setPath(true); 7779 pathModel.setCreateTable(true); 7780 TObjectName fileUri = new TObjectName(); 7781 fileUri.setString(stmt.getExternalStageURL()); 7782 TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri); 7783 7784 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7785 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 7786 relation.setTarget(new TableColumnRelationshipElement(locationColumn)); 7787 relation.setProcess(process); 7788 7789 } else { 7790 for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) { 7791 if (temp instanceof TPutStmt) { 7792 TPutStmt put = (TPutStmt) temp; 7793 TStageLocation stageLocation = put.getStageLocation(); 7794 if (stageLocation != null && stageLocation.getStageName() != null) { 7795 Table stage = modelManager.getTableByName( 7796 DlineageUtil.getTableFullName(stageLocation.getStageName().toString())); 7797 if (stage == tableModel) { 7798 TObjectName location = new TObjectName(); 7799 if (!SQLUtil.isEmpty(put.getFileName())) { 7800 location.setString(put.getFileName()); 7801 locationColumn = modelFactory.createStageLocation(tableModel, location); 7802 } 7803 break; 7804 } 7805 } 7806 } 7807 } 7808 } 7809 7810 String fileFormat = stmt.getFileFormatName(); 7811 if (fileFormat != null) { 7812 for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) { 7813 if (temp instanceof TCreateFileFormatStmt) { 7814 TCreateFileFormatStmt fileFormatStmt = (TCreateFileFormatStmt) temp; 7815 if (fileFormatStmt.getFileFormatName() != null 7816 && fileFormatStmt.getFileFormatName().toString().equalsIgnoreCase(fileFormat)) { 7817 tableModel.setFileType(fileFormatStmt.getTypeName()); 7818 break; 7819 } 7820 } 7821 } 7822 } 7823 7824 String procedureParent = getProcedureParentName(stmt); 7825 if (procedureParent != null) { 7826 tableModel.setParent(procedureParent); 7827 } 7828 7829 if (locationColumn != null) { 7830 List<Table> tables = modelManager.getTablesByName(); 7831 if (tables != null) { 7832 for (Table referTable : tables) { 7833 if (referTable.getLocation() != null && referTable.getLocation() 7834 .equals(DlineageUtil.getIdentifierNormalTableName(tableModel.getName()))) { 7835 for (int i = 0; i < referTable.getColumns().size(); i++) { 7836 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7837 relation.addSource(new TableColumnRelationshipElement(locationColumn)); 7838 relation.setTarget(new TableColumnRelationshipElement(referTable.getColumns().get(i))); 7839 } 7840 } 7841 } 7842 } 7843 } 7844 } else { 7845 ErrorInfo errorInfo = new ErrorInfo(); 7846 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 7847 errorInfo.setErrorMessage("Can't get target table. CreateStageStmt is " + stmt.toString()); 7848 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 7849 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 7850 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 7851 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 7852 ModelBindingManager.getGlobalHash())); 7853 errorInfo.fillInfo(this); 7854 errorInfos.add(errorInfo); 7855 } 7856 } 7857 7858 private void analyzeCreateExternalDataSourceStmt(TCreateExternalDataSourceStmt stmt) { 7859 TObjectName dataSourceName = stmt.getDataSourceName(); 7860 String locationUrl = stmt.getOption("LOCATION"); 7861 if (dataSourceName != null && locationUrl != null) { 7862 Table tableModel = modelFactory.createDataSource(dataSourceName); 7863 tableModel.setCreateTable(true); 7864 tableModel.setDataSource(true); 7865 tableModel.setLocation(locationUrl); 7866 7867 Process process = modelFactory.createProcess(stmt); 7868 tableModel.addProcess(process); 7869 7870 TObjectName location = new TObjectName(); 7871 location.setString(locationUrl); 7872 modelFactory.createTableColumn(tableModel, location, true); 7873 7874 String procedureParent = getProcedureParentName(stmt); 7875 if (procedureParent != null) { 7876 tableModel.setParent(procedureParent); 7877 } 7878 } else { 7879 ErrorInfo errorInfo = new ErrorInfo(); 7880 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 7881 errorInfo.setErrorMessage("Can't get target table. CreateExternalDataSourceStmt is " + stmt.toString()); 7882 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 7883 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 7884 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 7885 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 7886 ModelBindingManager.getGlobalHash())); 7887 errorInfo.fillInfo(this); 7888 errorInfos.add(errorInfo); 7889 } 7890 } 7891 7892 private void analyzeCreateStreamStmt(TCreateStreamStmt stmt) { 7893 TObjectName streamName = stmt.getStreamName(); 7894 7895 if (streamName != null) { 7896 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 7897 tableModel.setCreateTable(true); 7898 7899 Table streamModel = modelFactory.createStream(streamName); 7900 streamModel.setCreateTable(true); 7901 streamModel.setStream(true); 7902 7903 Process process = modelFactory.createProcess(stmt); 7904 tableModel.addProcess(process); 7905 7906 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7907 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(streamModel.getRelationRows())); 7908 relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 7909 relation.setProcess(process); 7910 } 7911 } 7912 7913 private String getProcedureParentName(TCustomSqlStatement stmt) { 7914 if (stmt instanceof TStoredProcedureSqlStatement) { 7915 if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) { 7916 return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString(); 7917 } 7918 } 7919 7920 stmt = stmt.getParentStmt(); 7921 if (stmt == null) 7922 return null; 7923 7924 if (stmt instanceof TCommonBlock) { 7925 if(((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) { 7926 stmt = (TStoredProcedureSqlStatement)((TCommonBlock) stmt).getBlockBody().getParentObjectName(); 7927 } 7928 } 7929 7930 if (stmt instanceof TStoredProcedureSqlStatement) { 7931 if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) { 7932 return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString(); 7933 } 7934 } 7935 if (stmt instanceof TTeradataCreateProcedure) { 7936 if (((TTeradataCreateProcedure) stmt).getProcedureName() != null) { 7937 return ((TTeradataCreateProcedure) stmt).getProcedureName().toString(); 7938 } 7939 } 7940 7941 return getProcedureParentName(stmt); 7942 } 7943 7944 private TStoredProcedureSqlStatement getProcedureParent(TCustomSqlStatement stmt) { 7945 if (stmt instanceof TStoredProcedureSqlStatement) { 7946 return (TStoredProcedureSqlStatement) stmt; 7947 } 7948 7949 stmt = stmt.getParentStmt(); 7950 if (stmt == null) 7951 return null; 7952 7953 if (stmt instanceof TCommonBlock) { 7954 if (((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) { 7955 stmt = (TStoredProcedureSqlStatement) ((TCommonBlock) stmt).getBlockBody().getParentObjectName(); 7956 } 7957 } 7958 7959 if (stmt instanceof TStoredProcedureSqlStatement) { 7960 return ((TStoredProcedureSqlStatement) stmt); 7961 } 7962 if (stmt instanceof TTeradataCreateProcedure) { 7963 return ((TTeradataCreateProcedure) stmt); 7964 } 7965 7966 return getProcedureParent(stmt); 7967 } 7968 7969 private void analyzeMergeStmt(TMergeSqlStatement stmt) { 7970 Object tableModel; 7971 Process process; 7972 if (stmt.getUsingTable() != null) { 7973 TTable table = stmt.getTargetTable(); 7974 if(table.getSubquery()!=null) { 7975 tableModel = modelFactory.createQueryTable(table); 7976 analyzeSelectStmt(table.getSubquery()); 7977 process = modelFactory.createProcess(stmt); 7978 } 7979 else { 7980 tableModel = modelFactory.createTable(table); 7981 process = modelFactory.createProcess(stmt); 7982 ((Table)tableModel).addProcess(process); 7983 } 7984 7985 for(TTable item: stmt.tables) { 7986 if(item.getSubquery()!=null) { 7987 continue; 7988 } 7989 Table tableItemModel = modelFactory.createTable(item); 7990 if (tableItemModel.getColumns() == null || tableItemModel.getColumns().isEmpty()) { 7991 tableItemModel.addColumnsFromSQLEnv(); 7992 } 7993 } 7994 7995 if (stmt.getUsingTable().getSubquery() != null) { 7996 QueryTable queryTable = modelFactory.createQueryTable(stmt.getUsingTable()); 7997 analyzeSelectStmt(stmt.getUsingTable().getSubquery()); 7998 7999 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getUsingTable().getSubquery()); 8000 8001 if (queryTable != null && resultSetModel != null && queryTable != resultSetModel) { 8002 if (queryTable.getColumns().size() == resultSetModel.getColumns().size()) { 8003 for (int i = 0; i < queryTable.getColumns().size(); i++) { 8004 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8005 relation.setEffectType(EffectType.select); 8006 relation.setTarget(new ResultColumnRelationshipElement(queryTable.getColumns().get(i))); 8007 relation.addSource(new ResultColumnRelationshipElement(resultSetModel.getColumns().get(i))); 8008 relation.setProcess(process); 8009 } 8010 } 8011 } 8012 8013 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 8014 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 8015 impactRelation.setEffectType(EffectType.merge); 8016 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 8017 resultSetModel.getRelationRows())); 8018 if (tableModel instanceof Table) { 8019 impactRelation.setTarget( 8020 new RelationRowsRelationshipElement<TableRelationRows>(((Table)tableModel).getRelationRows())); 8021 } 8022 else { 8023 impactRelation.setTarget( 8024 new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)tableModel).getRelationRows())); 8025 } 8026 } 8027 } else { 8028 if (stmt.getUsingTable().getAliasClause() != null && stmt.getUsingTable().getAliasClause().getColumns() != null && stmt.getUsingTable().getValueClause().getRows()!=null) { 8029 Table usingTable = modelFactory.createTableFromCreateDDL(stmt.getUsingTable(), false, stmt.getUsingTable().getAliasName() + stmt.getUsingTable().getTableName()); 8030 usingTable.setCreateTable(true); 8031 usingTable.setSubType(SubType.function); 8032 for (int z=0;z<stmt.getUsingTable().getAliasClause().getColumns().size();z++) { 8033 TObjectName columnName = stmt.getUsingTable().getAliasClause().getColumns().getObjectName(z); 8034 TableColumn tableColumn = modelFactory.createTableColumn(usingTable, columnName, true); 8035 TResultColumn resultColumn = stmt.getUsingTable().getValueClause().getRows().get(0).getResultColumn(z); 8036 modelManager.bindModel(resultColumn, tableColumn); 8037 analyzeResultColumnExpressionRelation(tableColumn, resultColumn.getExpr()); } 8038 } 8039 else { 8040 modelFactory.createTable(stmt.getUsingTable()); 8041 } 8042 } 8043 8044 8045 if (stmt.getWhenClauses() != null && stmt.getWhenClauses().size() > 0) { 8046 for (int i = 0; i < stmt.getWhenClauses().size(); i++) { 8047 TMergeWhenClause clause = stmt.getWhenClauses().getElement(i); 8048 if (clause.getCondition() != null) { 8049 analyzeFilterCondition(null, clause.getCondition(), null, null, EffectType.merge_when); 8050 } 8051 if (clause.getUpdateClause() != null) { 8052 TResultColumnList columns = clause.getUpdateClause().getUpdateColumnList(); 8053 if (columns == null || columns.size() == 0) 8054 continue; 8055 8056 ResultSet resultSet = modelFactory.createResultSet(clause.getUpdateClause(), false); 8057 createPseudoImpactRelation(stmt, resultSet, EffectType.merge_update); 8058 8059 for (int j = 0; j < columns.size(); j++) { 8060 TResultColumn resultColumn = columns.getResultColumn(j); 8061 if (resultColumn.getExpr().getLeftOperand() 8062 .getExpressionType() == EExpressionType.simple_object_name_t) { 8063 TObjectName columnObject = resultColumn.getExpr().getLeftOperand().getObjectOperand(); 8064 8065 if (columnObject.getDbObjectType() == EDbObjectType.variable) { 8066 continue; 8067 } 8068 8069 if (columnObject.getColumnNameOnly().startsWith("@") 8070 && (option.getVendor() == EDbVendor.dbvmssql 8071 || option.getVendor() == EDbVendor.dbvazuresql)) { 8072 continue; 8073 } 8074 8075 if (columnObject.getColumnNameOnly().startsWith(":") 8076 && (option.getVendor() == EDbVendor.dbvhana 8077 || option.getVendor() == EDbVendor.dbvteradata)) { 8078 continue; 8079 } 8080 8081 ResultColumn updateColumn = modelFactory.createMergeResultColumn(resultSet, 8082 columnObject); 8083 8084 TExpression valueExpression = resultColumn.getExpr().getRightOperand(); 8085 if (valueExpression == null) 8086 continue; 8087 8088 columnsInExpr visitor = new columnsInExpr(); 8089 valueExpression.inOrderTraverse(visitor); 8090 List<TObjectName> objectNames = visitor.getObjectNames(); 8091 List<TParseTreeNode> functions = visitor.getFunctions(); 8092 8093 if (functions != null && !functions.isEmpty()) { 8094 analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.merge_update); 8095 } 8096 8097 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 8098 if (subquerys != null && !subquerys.isEmpty()) { 8099 analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.merge_update); 8100 } 8101 8102 analyzeDataFlowRelation(updateColumn, objectNames, EffectType.merge_update, functions); 8103 8104 List<TParseTreeNode> constants = visitor.getConstants(); 8105 analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.merge_update, 8106 functions); 8107 8108 if (tableModel instanceof Table) { 8109 TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel, columnObject, 8110 false); 8111 8112 if (tableColumn != null) { 8113 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8114 relation.setEffectType(EffectType.merge_update); 8115 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8116 relation.addSource(new ResultColumnRelationshipElement(updateColumn)); 8117 relation.setProcess(process); 8118 } 8119 } 8120 else { 8121 TTable targetTable = stmt.getTargetTable().getSubquery().getTables().getTable(0); 8122 if (targetTable != null && modelManager.getModel(targetTable) instanceof Table) { 8123 Table targetTableModel = (Table) modelManager.getModel(targetTable); 8124 TableColumn tableColumn = modelFactory 8125 .createTableColumn((Table) targetTableModel, columnObject, false); 8126 if (tableColumn != null) { 8127 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8128 relation.setEffectType(EffectType.merge_update); 8129 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8130 relation.addSource(new ResultColumnRelationshipElement(updateColumn)); 8131 relation.setProcess(process); 8132 } 8133 } 8134 } 8135 } 8136 } 8137 } 8138 if (clause.getInsertClause() != null && tableModel instanceof Table) { 8139 TExpression insertValue = clause.getInsertClause().getInsertValue(); 8140 if (insertValue != null 8141 && insertValue.getExpressionType() == EExpressionType.objectConstruct_t) { 8142 ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false); 8143 8144 createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert); 8145 8146 TObjectConstruct objectConstruct = insertValue.getObjectConstruct(); 8147 for (int z = 0; z < objectConstruct.getPairs().size(); z++) { 8148 TPair pair = objectConstruct.getPairs().getElement(z); 8149 8150 if (pair.getKeyName().getExpressionType() == EExpressionType.simple_constant_t) { 8151 TObjectName columnObject = new TObjectName(); 8152 TConstant constant = pair.getKeyName().getConstantOperand(); 8153 TSourceToken newSt = new TSourceToken( 8154 constant.getValueToken().getTextWithoutQuoted()); 8155 columnObject.setPartToken(newSt); 8156 columnObject.setSourceTable(stmt.getTargetTable()); 8157 columnObject.setStartToken(constant.getStartToken()); 8158 columnObject.setEndToken(constant.getEndToken()); 8159 8160 ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet, 8161 columnObject); 8162 8163 TExpression valueExpression = pair.getKeyValue(); 8164 if (valueExpression == null) 8165 continue; 8166 8167 columnsInExpr visitor = new columnsInExpr(); 8168 valueExpression.inOrderTraverse(visitor); 8169 List<TObjectName> objectNames = visitor.getObjectNames(); 8170 List<TParseTreeNode> functions = visitor.getFunctions(); 8171 8172 if (functions != null && !functions.isEmpty()) { 8173 analyzeFunctionDataFlowRelation(insertColumn, functions, 8174 EffectType.merge_insert); 8175 } 8176 8177 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 8178 if (subquerys != null && !subquerys.isEmpty()) { 8179 analyzeSubqueryDataFlowRelation(insertColumn, subquerys, 8180 EffectType.merge_insert); 8181 } 8182 8183 analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert, 8184 functions); 8185 8186 List<TParseTreeNode> constants = visitor.getConstants(); 8187 analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert, 8188 functions); 8189 8190 TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel, 8191 columnObject, false); 8192 8193 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8194 relation.setEffectType(EffectType.merge_insert); 8195 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8196 relation.addSource(new ResultColumnRelationshipElement(insertColumn)); 8197 relation.setProcess(process); 8198 } 8199 } 8200 } else { 8201 TObjectNameList columns = clause.getInsertClause().getColumnList(); 8202 TResultColumnList values = clause.getInsertClause().getValuelist(); 8203 if (values == null || values.size() == 0) { 8204 if (clause.getInsertClause().toString().toLowerCase().indexOf("row") != -1) { 8205 if (stmt.getUsingTable().getSubquery() != null) { 8206 ResultSet sourceResultSet = modelFactory.createQueryTable(stmt.getUsingTable()); 8207 TObjectName targetStarColumn = new TObjectName(); 8208 targetStarColumn.setString("*"); 8209 TableColumn targetTableColumn = modelFactory.createTableColumn((Table)tableModel, 8210 targetStarColumn, true); 8211 if (sourceResultSet.getColumns() == null 8212 || sourceResultSet.getColumns().isEmpty()) { 8213 TObjectName sourceStarColumn = new TObjectName(); 8214 sourceStarColumn.setString("*"); 8215 modelFactory.createResultColumn(sourceResultSet, sourceStarColumn); 8216 } 8217 for (ResultColumn sourceColumn : sourceResultSet.getColumns()) { 8218 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8219 relation.setEffectType(EffectType.merge_insert); 8220 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 8221 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 8222 relation.setProcess(process); 8223 } 8224 } else { 8225 Table sourceTable = modelFactory.createTable(stmt.getUsingTable()); 8226 TObjectName sourceStarColumn = new TObjectName(); 8227 sourceStarColumn.setString("*"); 8228 TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, 8229 sourceStarColumn, true); 8230 TObjectName targetStarColumn = new TObjectName(); 8231 targetStarColumn.setString("*"); 8232 TableColumn targetTableColumn = modelFactory.createTableColumn(((Table)tableModel), 8233 targetStarColumn, true); 8234 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8235 relation.setEffectType(EffectType.merge_insert); 8236 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 8237 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 8238 relation.setProcess(process); 8239 } 8240 8241 } 8242 continue; 8243 } 8244 8245 List<TObjectName> tableColumns = new ArrayList<TObjectName>(); 8246 if (columns == null || columns.size() == 0) { 8247// if (!((Table)tableModel).getColumns().isEmpty()) { 8248// for (int j = 0; j < ((Table)tableModel).getColumns().size(); j++) { 8249// if (((Table)tableModel).getColumns().get(j).getColumnObject() == null) { 8250// continue; 8251// } 8252// tableColumns.add(((Table)tableModel).getColumns().get(j).getColumnObject()); 8253// } 8254// } else { 8255 for (int j = 0; j < values.size(); j++) { 8256 TResultColumn column = values.getResultColumn(j); 8257 if (column.getAliasClause() != null) { 8258 tableColumns.add(column.getAliasClause().getAliasName()); 8259 } else if (column.getFieldAttr() != null) { 8260 tableColumns.add(column.getFieldAttr()); 8261 } else { 8262 TObjectName columnName = new TObjectName(); 8263 columnName.setString(column.toString()); 8264 tableColumns.add(columnName); 8265 } 8266// } 8267 } 8268 } else { 8269 for (int j = 0; j < columns.size(); j++) { 8270 tableColumns.add(columns.getObjectName(j)); 8271 } 8272 } 8273 8274 ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false); 8275 8276 createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert); 8277 8278 for (int j = 0; j < tableColumns.size() && j < values.size(); j++) { 8279 TObjectName columnObject = tableColumns.get(j); 8280 8281 ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet, 8282 columnObject); 8283 8284 TExpression valueExpression = values.getResultColumn(j).getExpr(); 8285 if (valueExpression == null) 8286 continue; 8287 8288 columnsInExpr visitor = new columnsInExpr(); 8289 valueExpression.inOrderTraverse(visitor); 8290 List<TObjectName> objectNames = visitor.getObjectNames(); 8291 List<TParseTreeNode> functions = visitor.getFunctions(); 8292 8293 if (functions != null && !functions.isEmpty()) { 8294 analyzeFunctionDataFlowRelation(insertColumn, functions, EffectType.merge_insert); 8295 } 8296 8297 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 8298 if (subquerys != null && !subquerys.isEmpty()) { 8299 analyzeSubqueryDataFlowRelation(insertColumn, subquerys, EffectType.merge_insert); 8300 } 8301 8302 analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert, functions); 8303 8304 List<TParseTreeNode> constants = visitor.getConstants(); 8305 analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert, 8306 functions); 8307 8308 TableColumn tableColumn = modelFactory.createTableColumn(((Table)tableModel), columnObject, 8309 false); 8310 if(tableColumn == null) { 8311 if (((Table) tableModel).isCreateTable()) { 8312 tableColumn = ((Table) tableModel).getColumns().get(j); 8313 } 8314 else { 8315 continue; 8316 } 8317 } 8318 8319 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8320 relation.setEffectType(EffectType.merge_insert); 8321 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8322 relation.addSource(new ResultColumnRelationshipElement(insertColumn)); 8323 relation.setProcess(process); 8324 } 8325 } 8326 } 8327 } 8328 8329 } 8330 8331 if (stmt.getCondition() != null) { 8332 analyzeFilterCondition(null, stmt.getCondition(), null, JoinClauseType.on, EffectType.merge); 8333 } 8334 } 8335 } 8336 8337 private List<TableColumn> bindInsertTableColumn(Table tableModel, TInsertIntoValue value, List<TObjectName> keyMap, 8338 List<TResultColumn> valueMap) { 8339 List<TableColumn> tableColumns = new ArrayList<TableColumn>(); 8340 if (value.getColumnList() != null) { 8341 for (int z = 0; z < value.getColumnList().size(); z++) { 8342 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 8343 value.getColumnList().getObjectName(z)); 8344 tableColumns.add(tableColumn); 8345 keyMap.add(tableColumn.getColumnObject()); 8346 } 8347 } 8348 8349 if (value.getTargetList() != null) { 8350 for (int z = 0; z < value.getTargetList().size(); z++) { 8351 TMultiTarget target = value.getTargetList().getMultiTarget(z); 8352 TResultColumnList columns = target.getColumnList(); 8353 for (int i = 0; i < columns.size(); i++) { 8354 if (value.getColumnList() == null) { 8355 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 8356 columns.getResultColumn(i).getFieldAttr()); 8357 tableColumns.add(tableColumn); 8358 } 8359 valueMap.add(columns.getResultColumn(i)); 8360 } 8361 } 8362 } 8363 8364 return tableColumns; 8365 } 8366 8367 private TableColumn matchColumn(List<TableColumn> tableColumns, TableColumn targetColumn) { 8368 String columnName = targetColumn.getName(); 8369 if (tableColumns == null) { 8370 return null; 8371 } 8372 for (int i = 0; i < tableColumns.size(); i++) { 8373 TableColumn column = tableColumns.get(i); 8374 if (column.getColumnObject() == null) { 8375 continue; 8376 } 8377 if(column.isStruct() && targetColumn.isStruct()) { 8378 List<String> names = SQLUtil.parseNames(column.getName()); 8379 List<String> targetNames = SQLUtil 8380 .parseNames(targetColumn.getName()); 8381 if (!getColumnName(targetNames.get(0)) 8382 .equals(getColumnName(names.get(0)))) { 8383 continue; 8384 } 8385 } 8386 if (getColumnName(column.getColumnObject().toString()).equals(getColumnName(columnName))) { 8387 return column; 8388 } 8389 } 8390 return null; 8391 } 8392 8393 private TableColumn matchColumn(List<TableColumn> tableColumns, TObjectName columnName) { 8394 if (tableColumns == null) { 8395 return null; 8396 } 8397 for (int i = 0; i < tableColumns.size(); i++) { 8398 TableColumn column = tableColumns.get(i); 8399 if (column.getColumnObject() == null) { 8400 continue; 8401 } 8402 if (DlineageUtil.getColumnName(column.getColumnObject()).equalsIgnoreCase(DlineageUtil.getColumnName(columnName))) 8403 return column; 8404 } 8405 return null; 8406 } 8407 8408 private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, ResultColumn resultColumn) { 8409 if (resultColumns == null) { 8410 return null; 8411 } 8412 8413 TObjectName columnName = getObjectName(resultColumn); 8414 if (columnName == null) { 8415 return null; 8416 } 8417 8418 for (int i = 0; i < resultColumns.size(); i++) { 8419 ResultColumn column = resultColumns.get(i); 8420 if (column.getAlias() != null 8421 && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName))) 8422 return column; 8423 if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName))) 8424 return column; 8425 if (column.getName() != null && column.getName().endsWith("*")) { 8426 if ("*".equals(column.getColumnObject().toString())) { 8427 return column; 8428 } else { 8429 TObjectName columnObjectName = getObjectName(column); 8430 if (columnObjectName.getTableString() != null 8431 && columnObjectName.getTableString().equals(getResultSetAlias(resultColumn))) { 8432 return column; 8433 } 8434 } 8435 } 8436 } 8437 return null; 8438 } 8439 8440 private String getResultSetAlias(ResultColumn resultColumn) { 8441 ResultSet resultSet = resultColumn.getResultSet(); 8442 if (resultSet instanceof QueryTable) { 8443 return ((QueryTable) resultSet).getAlias(); 8444 } 8445 return null; 8446 } 8447 8448 private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, TObjectName columnName) { 8449 if (resultColumns == null) { 8450 return null; 8451 } 8452 for (int i = 0; i < resultColumns.size(); i++) { 8453 ResultColumn column = resultColumns.get(i); 8454 if (column.getAlias() != null 8455 && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName))) 8456 return column; 8457 if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName))) 8458 return column; 8459 if (column.getName() != null && column.getName().endsWith("*")) { 8460 if ("*".equals(column.getColumnObject().toString())) { 8461 return column; 8462 } else { 8463 TObjectName columnObjectName = getObjectName(column); 8464 if (columnObjectName.getTableString() != null 8465 && columnObjectName.getTableString().equals(columnName.getTableString())) { 8466 return column; 8467 } 8468 } 8469 } 8470 } 8471 return null; 8472 } 8473 8474 private void analyzeInsertStmt(TInsertSqlStatement stmt) { 8475 Map<Table, List<TObjectName>> insertTableKeyMap = new LinkedHashMap<Table, List<TObjectName>>(); 8476 Map<Table, List<TResultColumn>> insertTableValueMap = new LinkedHashMap<Table, List<TResultColumn>>(); 8477 Map<String, List<TableColumn>> tableColumnMap = new LinkedHashMap<String, List<TableColumn>>(); 8478 List<Table> inserTables = new ArrayList<Table>(); 8479 List<TExpression> expressions = new ArrayList<TExpression>(); 8480 boolean hasInsertColumns = false; 8481 8482 EffectType effectType = EffectType.insert; 8483 if(stmt.getInsertToken()!=null && stmt.getInsertToken().toString().toLowerCase().startsWith("replace")) { 8484 effectType = EffectType.replace; 8485 } 8486 8487 if (stmt.getInsertConditions() != null && stmt.getInsertConditions().size() > 0) { 8488 for (int i = 0; i < stmt.getInsertConditions().size(); i++) { 8489 TInsertCondition condition = stmt.getInsertConditions().getElement(i); 8490 if (condition.getCondition() != null) { 8491 expressions.add(condition.getCondition()); 8492 } 8493 for (int j = 0; j < condition.getInsertIntoValues().size(); j++) { 8494 TInsertIntoValue value = condition.getInsertIntoValues().getElement(j); 8495 TTable table = value.getTable(); 8496 Table tableModel = modelFactory.createTable(table); 8497 8498 inserTables.add(tableModel); 8499 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 8500 List<TResultColumn> valueMap = new ArrayList<TResultColumn>(); 8501 insertTableKeyMap.put(tableModel, keyMap); 8502 insertTableValueMap.put(tableModel, valueMap); 8503 8504 List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap); 8505 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null 8506 && !tableColumns.isEmpty()) { 8507 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), 8508 tableColumns); 8509 } 8510 8511 // if (stmt.getSubQuery() != null) 8512 { 8513 Process process = modelFactory.createProcess(stmt); 8514 tableModel.addProcess(process); 8515 } 8516 } 8517 } 8518 hasInsertColumns = true; 8519 } else if (stmt.getInsertIntoValues() != null && stmt.getInsertIntoValues().size() > 0) { 8520 for (int i = 0; i < stmt.getInsertIntoValues().size(); i++) { 8521 TInsertIntoValue value = stmt.getInsertIntoValues().getElement(i); 8522 TTable table = value.getTable(); 8523 Table tableModel = modelFactory.createTable(table); 8524 8525 inserTables.add(tableModel); 8526 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 8527 List<TResultColumn> valueMap = new ArrayList<TResultColumn>(); 8528 insertTableKeyMap.put(tableModel, keyMap); 8529 insertTableValueMap.put(tableModel, valueMap); 8530 8531 List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap); 8532 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) { 8533 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns); 8534 } 8535 8536 // if (stmt.getSubQuery() != null) 8537 { 8538 Process process = modelFactory.createProcess(stmt); 8539 tableModel.addProcess(process); 8540 } 8541 } 8542 hasInsertColumns = true; 8543 } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) { 8544 TTable table = stmt.getTargetTable(); 8545 Table tableModel = modelFactory.createTable(table); 8546 8547 inserTables.add(tableModel); 8548 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 8549 insertTableKeyMap.put(tableModel, keyMap); 8550 List<TableColumn> tableColumns = new ArrayList<TableColumn>(); 8551 for (int i = 0; i < stmt.getColumnList().size(); i++) { 8552 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 8553 stmt.getColumnList().getObjectName(i)); 8554 tableColumns.add(tableColumn); 8555 } 8556 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) { 8557 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns); 8558 } 8559 8560 // if (stmt.getSubQuery() != null) 8561 { 8562 Process process = modelFactory.createProcess(stmt); 8563 tableModel.addProcess(process); 8564 } 8565 hasInsertColumns = true; 8566 } else if (stmt.getOutputClause() != null && stmt.getOutputClause().getSelectItemList().size() > 0) { 8567 TTable table = stmt.getTargetTable(); 8568 Table tableModel = modelFactory.createTable(table); 8569 8570 inserTables.add(tableModel); 8571 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 8572 insertTableKeyMap.put(tableModel, keyMap); 8573 List<TableColumn> tableColumns = new ArrayList<TableColumn>(); 8574 for (int i = 0; i < stmt.getOutputClause().getSelectItemList().size(); i++) { 8575 TObjectName columnName = stmt.getOutputClause().getSelectItemList().getResultColumn(i).getFieldAttr(); 8576 if (columnName.getPseudoTableType() != EPseudoTableType.none) { 8577 // Phase 1 already swapped tokens; getColumnNameOnly() returns actual column name 8578 String column = columnName.getColumnNameOnly(); 8579 columnName = new TObjectName(); 8580 columnName.setString(column); 8581 } else { 8582 String column = columnName.toString().toLowerCase(); 8583 if ((column.startsWith("inserted.") || column.startsWith("deleted.")) 8584 && columnName.getPropertyToken() != null) { 8585 column = columnName.getPropertyToken().getAstext(); 8586 columnName = new TObjectName(); 8587 columnName.setString(column); 8588 } 8589 } 8590 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, columnName); 8591 tableColumns.add(tableColumn); 8592 } 8593 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) { 8594 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns); 8595 } 8596 8597 // if (stmt.getSubQuery() != null) 8598 { 8599 Process process = modelFactory.createProcess(stmt); 8600 tableModel.addProcess(process); 8601 } 8602 hasInsertColumns = true; 8603 } else { 8604 TTable table = stmt.getTargetTable(); 8605 Table tableModel; 8606 if (table != null) { 8607 tableModel = modelFactory.createTable(table); 8608 // if (stmt.getSubQuery() != null) 8609 { 8610 Process process = modelFactory.createProcess(stmt); 8611 tableModel.addProcess(process); 8612 } 8613 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 8614 tableModel.addColumnsFromSQLEnv(); 8615 } 8616 } else if (stmt.getDirectoryName() != null) { 8617 tableModel = modelFactory.createTableByName(stmt.getDirectoryName(), true); 8618 tableModel.setPath(true); 8619 tableModel.setCreateTable(true); 8620 TObjectName fileUri = new TObjectName(); 8621 fileUri.setString("uri=" + stmt.getDirectoryName()); 8622 TableColumn tableColumn = modelFactory.createFileUri(tableModel, fileUri); 8623 // if (stmt.getSubQuery() != null) 8624 { 8625 Process process = modelFactory.createProcess(stmt); 8626 tableModel.addProcess(process); 8627 } 8628 } else { 8629 ErrorInfo errorInfo = new ErrorInfo(); 8630 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 8631 errorInfo.setErrorMessage("Can't get target table. InsertSqlStatement is " + stmt.toString()); 8632 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 8633 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 8634 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 8635 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 8636 ModelBindingManager.getGlobalHash())); 8637 errorInfo.fillInfo(this); 8638 errorInfos.add(errorInfo); 8639 return; 8640 } 8641 inserTables.add(tableModel); 8642 if (table != null 8643 && tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null) { 8644 if (tableModel.getColumns() != null && !tableModel.getColumns().isEmpty()) { 8645 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), 8646 tableModel.getColumns()); 8647 } else { 8648 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), null); 8649 } 8650 } 8651 } 8652 8653 if (stmt.getSubQuery() != null) { 8654 analyzeSelectStmt(stmt.getSubQuery()); 8655 } 8656 8657 Iterator<Table> tableIter = inserTables.iterator(); 8658 while (tableIter.hasNext()) { 8659 Table tableModel = tableIter.next(); 8660 List<TableColumn> tableColumns = tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())); 8661 List<TObjectName> keyMap = insertTableKeyMap.get(tableModel); 8662 List<TResultColumn> valueMap = insertTableValueMap.get(tableModel); 8663 boolean initColumn = (hasInsertColumns && tableColumns != null && !containStarColumn(tableColumns)); 8664 8665 if (stmt.getSubQuery() != null) { 8666 8667 List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>(); 8668 if (stmt.getSubQuery().getResultColumnList() != null || stmt.getSubQuery().getTransformClause() != null) { 8669 subquerys.add(stmt.getSubQuery()); 8670 } else if (stmt.getSubQuery().getValueClause() != null 8671 && stmt.getSubQuery().getValueClause().getRows() != null) { 8672 for (TResultColumnList resultColumnList : stmt.getSubQuery().getValueClause().getRows()) { 8673 for(TResultColumn resultColumn: resultColumnList) { 8674 if(resultColumn.getExpr()!=null && resultColumn.getExpr().getSubQuery()!=null) { 8675 analyzeSelectStmt(resultColumn.getExpr().getSubQuery()); 8676 subquerys.add(resultColumn.getExpr().getSubQuery()); 8677 } 8678 } 8679 } 8680 } 8681 8682 for(TSelectSqlStatement subquery: subquerys) { 8683 if ((tableModel.isCreateTable() && tableModel.getColumns() != null) 8684 || (subquery.getSetOperatorType() == ESetOperatorType.none 8685 && stmt.getColumnList() != null && stmt.getColumnList().size() > 0)) { 8686 8687 ResultSet resultSetModel = null; 8688 8689 if (subquery != null) { 8690 resultSetModel = (ResultSet) modelManager.getModel(subquery); 8691 } 8692 8693 TResultColumnList resultset = subquery.getResultColumnList(); 8694 if (resultSetModel == null && resultset != null) { 8695 resultSetModel = (ResultSet) modelManager.getModel(resultset); 8696 } 8697 8698 if (resultSetModel == null) { 8699 ErrorInfo errorInfo = new ErrorInfo(); 8700 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 8701 errorInfo.setErrorMessage("Can't get resultset model"); 8702 errorInfo.setStartPosition(new Pair3<Long, Long, String>(resultset.getStartToken().lineNo, 8703 resultset.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 8704 errorInfo.setEndPosition(new Pair3<Long, Long, String>(resultset.getEndToken().lineNo, 8705 resultset.getEndToken().columnNo + resultset.getEndToken().getAstext().length(), 8706 ModelBindingManager.getGlobalHash())); 8707 errorInfos.add(errorInfo); 8708 } 8709 8710 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 8711 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 8712 impactRelation.setEffectType(effectType); 8713 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 8714 resultSetModel.getRelationRows())); 8715 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 8716 tableModel.getRelationRows())); 8717 } 8718 8719 int resultSetSize = resultSetModel.getColumns().size(); 8720 int j = 0; 8721 int starIndex = 0; 8722 TObjectNameList items = stmt.getColumnList(); 8723 List<String> itemNames = new ArrayList<String>(); 8724 int starColumnCount = 0; 8725 for (ResultColumn item : resultSetModel.getColumns()) { 8726 if (item.getName().endsWith("*")) { 8727 starColumnCount += 1; 8728 } 8729 } 8730 if (items != null) { 8731 for (int i = 0; i < items.size() && j < resultSetSize; i++) { 8732 TObjectName column = items.getObjectName(i); 8733 8734 if (column.getDbObjectType() == EDbObjectType.variable) { 8735 continue; 8736 } 8737 8738 if (column.getColumnNameOnly().startsWith("@") 8739 && (option.getVendor() == EDbVendor.dbvmssql 8740 || option.getVendor() == EDbVendor.dbvazuresql)) { 8741 continue; 8742 } 8743 8744 if (column.getColumnNameOnly().startsWith(":") 8745 && (option.getVendor() == EDbVendor.dbvhana 8746 || option.getVendor() == EDbVendor.dbvteradata)) { 8747 continue; 8748 } 8749 8750 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 8751 if (!resultSetModel.getColumns().get(j).getName().contains("*")) { 8752 j++; 8753 } else { 8754 starIndex++; 8755 if (resultSetSize - j == items.size() - i) { 8756 j++; 8757 8758 } 8759 } 8760 if (column != null) { 8761 TableColumn tableColumn; 8762 // if (!initColumn) { 8763 tableColumn = matchColumn(tableModel.getColumns(), column); 8764 if (tableColumn == null) { 8765 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 8766 if (tableModel.getColumns().size() <= i) { 8767 continue; 8768 } 8769 tableColumn = tableModel.getColumns().get(i); 8770 } else { 8771 tableColumn = modelFactory.createTableColumn(tableModel, column, false); 8772 if(tableColumn == null) { 8773 continue; 8774 } 8775 } 8776 } 8777// } else { 8778// tableColumn = matchColumn(tableColumns, column); 8779// if (tableColumn == null) { 8780// continue; 8781// } 8782// } 8783 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8784 relation.setEffectType(effectType); 8785 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8786 if (resultColumn.hasStarLinkColumn() 8787 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1 && starColumnCount<=1) { 8788 boolean find = false; 8789 while (resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 8790 TObjectName name = resultColumn.getStarLinkColumnName(starIndex - 1); 8791 if (itemNames.contains(name.toString())) { 8792 starIndex++; 8793 continue; 8794 } 8795 ResultColumn expandStarColumn = modelFactory 8796 .createResultColumn(resultSetModel, name, false); 8797 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 8798 itemNames.add(resultColumn.getName()); 8799 find = true; 8800 break; 8801 } 8802 if (!find) { 8803 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 8804 itemNames.add(resultColumn.getName()); 8805 } 8806 } else { 8807 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 8808 itemNames.add(resultColumn.getName()); 8809 } 8810 Process process = modelFactory.createProcess(stmt); 8811 relation.setProcess(process); 8812 } 8813 } 8814 } else { 8815 List<TableColumn> columns = tableModel.getColumns(); 8816 if (columns.size() == 1 && tableModel.isPath()) { 8817 for(int i=0;i<resultSetSize;i++) { 8818 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 8819 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8820 relation.setEffectType(effectType); 8821 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(0))); 8822 if (resultColumn.hasStarLinkColumn() 8823 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 8824 ResultColumn expandStarColumn = modelFactory.createResultColumn( 8825 resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1), 8826 false); 8827 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 8828 } else { 8829 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 8830 } 8831 Process process = modelFactory.createProcess(stmt); 8832 relation.setProcess(process); 8833 } 8834 } else { 8835 boolean fromStruct = false; 8836 for (int i = 0; i < columns.size() && j < resultSetSize; i++) { 8837 String column = columns.get(i).getName(); 8838 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 8839 if (!resultColumn.getName().contains("*")) { 8840 if (resultColumn.getName().equals(resultColumn.getRefColumnName()) 8841 && resultColumn.getColumnObject().toString().endsWith("*") 8842 && resultSetSize == 1) { 8843 starIndex++; 8844 if (resultSetSize - j == columns.size() - i) { 8845 j++; 8846 8847 } 8848 } 8849 else { 8850 j++; 8851 } 8852 } else { 8853 starIndex++; 8854 if (resultSetSize - j == columns.size() - i) { 8855 j++; 8856 8857 } 8858 } 8859 if (column != null) { 8860 TableColumn tableColumn; 8861 // if (!initColumn) { 8862 tableColumn = matchColumn(tableModel.getColumns(), columns.get(i)); 8863 if (tableColumn == null) { 8864 if (tableModel.isCreateTable() 8865 && !containStarColumn(tableModel.getColumns())) { 8866 if (tableModel.getColumns().size() <= i) { 8867 continue; 8868 } 8869 tableColumn = tableModel.getColumns().get(i); 8870 } else { 8871 TObjectName columnName = new TObjectName(); 8872 columnName.setString(column); 8873 tableColumn = modelFactory.createTableColumn(tableModel, columnName, 8874 false); 8875 } 8876 } 8877 else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) { 8878 j--; 8879 fromStruct = true; 8880 } 8881 if(fromStruct && !tableColumn.isStruct()) { 8882 fromStruct = false; 8883 resultColumn = resultSetModel.getColumns().get(j); 8884 j++; 8885 } 8886 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8887 relation.setEffectType(effectType); 8888 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8889 if (resultColumn.hasStarLinkColumn() 8890 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 8891 ResultColumn expandStarColumn = modelFactory.createResultColumn( 8892 resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1), 8893 false); 8894 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 8895 } else { 8896 relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1)); 8897 } 8898 Process process = modelFactory.createProcess(stmt); 8899 relation.setProcess(process); 8900 } 8901 } 8902 } 8903 } 8904 } else if (!subquery.isCombinedQuery()) { 8905 SelectResultSet resultSetModel = (SelectResultSet) modelManager 8906 .getModel(subquery.getResultColumnList() != null ? subquery.getResultColumnList() 8907 : subquery.getTransformClause()); 8908 8909 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 8910 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 8911 impactRelation.setEffectType(effectType); 8912 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 8913 resultSetModel.getRelationRows())); 8914 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 8915 tableModel.getRelationRows())); 8916 } 8917 8918 List<ResultColumn> columnsSnapshot = new ArrayList<ResultColumn>(); 8919 columnsSnapshot.addAll(resultSetModel.getColumns()); 8920 if(resultSetModel.isDetermined() && stmt.getColumnList() == null) { 8921 tableModel.setDetermined(true); 8922 } 8923 for (int i = 0; i < columnsSnapshot.size(); i++) { 8924 ResultColumn resultColumn = columnsSnapshot.get(i); 8925 if (resultColumn.getColumnObject() instanceof TObjectName) { 8926 TableColumn tableColumn; 8927 if (!initColumn) { 8928 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 8929 if (tableModel.getColumns().size() <= i) { 8930 continue; 8931 } 8932 tableColumn = tableModel.getColumns().get(i); 8933 } else { 8934 tableColumn = modelFactory.createInsertTableColumn(tableModel, 8935 (TObjectName) resultColumn.getColumnObject()); 8936 } 8937 if (containStarColumn(tableColumns)) { 8938 getStarColumn(tableColumns) 8939 .bindStarLinkColumn((TObjectName) resultColumn.getColumnObject()); 8940 } 8941 } else { 8942 TObjectName matchedColumnName = (TObjectName) resultColumn.getColumnObject(); 8943 tableColumn = matchColumn(tableColumns, matchedColumnName); 8944 if (tableColumn == null) { 8945 if (!isEmptyCollection(valueMap)) { 8946 int index = indexOfColumn(valueMap, matchedColumnName); 8947 if (index != -1) { 8948 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 8949 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 8950 } else if (isEmptyCollection(keyMap) && index < tableColumns.size()) { 8951 tableColumn = tableColumns.get(index); 8952 } else { 8953 continue; 8954 } 8955 } else { 8956 continue; 8957 } 8958 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 8959 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 8960 } else if (isEmptyCollection(keyMap) && isEmptyCollection(valueMap) 8961 && i < tableColumns.size()) { 8962 tableColumn = tableColumns.get(i); 8963 } else { 8964 continue; 8965 } 8966 } 8967 } 8968 8969 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8970 relation.setEffectType(effectType); 8971 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8972 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 8973 Process process = modelFactory.createProcess(stmt); 8974 relation.setProcess(process); 8975 } else { 8976 TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause(); 8977 if (alias != null && alias.getAliasName() != null) { 8978 TableColumn tableColumn; 8979 if (!initColumn) { 8980 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 8981 if (tableModel.getColumns().size() <= i) { 8982 if (tableModel.isPath()) { 8983 tableColumn = tableModel.getColumns().get(0); 8984 } else { 8985 continue; 8986 } 8987 } else { 8988 tableColumn = tableModel.getColumns().get(i); 8989 } 8990 } else { 8991 tableColumn = modelFactory.createInsertTableColumn(tableModel, 8992 alias.getAliasName()); 8993 if (containStarColumn(resultSetModel)) { 8994 tableColumn.notBindStarLinkColumn(true); 8995 } 8996 } 8997 if (containStarColumn(tableColumns)) { 8998 getStarColumn(tableColumns).bindStarLinkColumn(alias.getAliasName()); 8999 } 9000 } else { 9001 TObjectName matchedColumnName = alias.getAliasName(); 9002 tableColumn = matchColumn(tableColumns, matchedColumnName); 9003 if (tableColumn == null) { 9004 if (!isEmptyCollection(valueMap)) { 9005 int index = indexOfColumn(valueMap, matchedColumnName); 9006 if (index != -1) { 9007 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 9008 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 9009 } else if (isEmptyCollection(keyMap) 9010 && index < tableColumns.size()) { 9011 tableColumn = tableColumns.get(index); 9012 } else { 9013 continue; 9014 } 9015 } else { 9016 continue; 9017 } 9018 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 9019 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 9020 } else { 9021 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9022 alias.getAliasName()); 9023 } 9024 } 9025 9026 } 9027 9028 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9029 relation.setEffectType(effectType); 9030 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9031 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9032 Process process = modelFactory.createProcess(stmt); 9033 relation.setProcess(process); 9034 9035 } else if (((TResultColumn) resultColumn.getColumnObject()).getFieldAttr() != null) { 9036 TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject()) 9037 .getFieldAttr(); 9038 9039 Object model = modelManager.getModel( resultColumn.getColumnObject()); 9040 9041 TableColumn tableColumn; 9042 if (!initColumn) { 9043 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9044 if (fieldAttr.toString().endsWith("*")) { 9045 int starIndex = 0; 9046 for (TableColumn column : tableModel.getColumns()) { 9047 starIndex++; 9048 DataFlowRelationship relation = modelFactory 9049 .createDataFlowRelation(); 9050 relation.setEffectType(effectType); 9051 relation.setTarget(new TableColumnRelationshipElement(column)); 9052 if (resultColumn.getStarLinkColumnList().size() == tableModel 9053 .getColumns().size()) { 9054 ResultColumn expandStarColumn = modelFactory.createResultColumn( 9055 resultSetModel, 9056 resultColumn.getStarLinkColumnList().get(starIndex - 1), 9057 false); 9058 relation.addSource( 9059 new ResultColumnRelationshipElement(expandStarColumn)); 9060 } else { 9061 relation.addSource( 9062 new ResultColumnRelationshipElement(resultColumn)); 9063 } 9064 Process process = modelFactory.createProcess(stmt); 9065 relation.setProcess(process); 9066 } 9067 continue; 9068 } 9069 if (tableModel.getColumns().size() <= i) { 9070 continue; 9071 } 9072 tableColumn = tableModel.getColumns().get(i); 9073 } else { 9074 if(model instanceof LinkedHashMap) { 9075 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 9076 for(String key: resultColumns.keySet()) { 9077 tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName()); 9078 DataFlowRelationship relation = modelFactory 9079 .createDataFlowRelation(); 9080 relation.setEffectType(effectType); 9081 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9082 relation.addSource( 9083 new ResultColumnRelationshipElement(resultColumns.get(key))); 9084 Process process = modelFactory.createProcess(stmt); 9085 relation.setProcess(process); 9086 } 9087 continue; 9088 } 9089 else { 9090 tableColumn = modelFactory.createInsertTableColumn(tableModel, fieldAttr); 9091 } 9092 } 9093 } else if (tableModel.isDetermined() && i < tableModel.getColumns().size()) { 9094 if (!isEmptyCollection(valueMap)) { 9095 TObjectName matchedColumnName = fieldAttr; 9096 int index = indexOfColumn(valueMap, matchedColumnName); 9097 if (index != -1) { 9098 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 9099 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 9100 } else if (isEmptyCollection(keyMap) 9101 && index < tableColumns.size()) { 9102 tableColumn = tableColumns.get(index); 9103 } else { 9104 continue; 9105 } 9106 } else { 9107 continue; 9108 } 9109 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 9110 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 9111 } else { 9112 tableColumn = tableModel.getColumns().get(i); 9113 } 9114 } else { 9115 TObjectName matchedColumnName = fieldAttr; 9116 tableColumn = matchColumn(tableColumns, matchedColumnName); 9117 if (tableColumn == null) { 9118 if (!isEmptyCollection(valueMap)) { 9119 int index = indexOfColumn(valueMap, matchedColumnName); 9120 if (index != -1) { 9121 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 9122 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 9123 } else if (isEmptyCollection(keyMap) 9124 && index < tableColumns.size()) { 9125 tableColumn = tableColumns.get(index); 9126 } else { 9127 continue; 9128 } 9129 } else { 9130 continue; 9131 } 9132 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 9133 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 9134 } else { 9135 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9136 fieldAttr); 9137 } 9138 } 9139 } 9140 9141 if (!"*".equals(getColumnName(tableColumn.getColumnObject())) 9142 && "*".equals(getColumnName(fieldAttr))) { 9143 TObjectName columnObject = fieldAttr; 9144 TTable sourceTable = columnObject.getSourceTable(); 9145 if (columnObject.getTableToken() != null && sourceTable != null) { 9146 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 9147 for (int j = 0; j < columns.length; j++) { 9148 TObjectName columnName = columns[j]; 9149 if (columnName == null || "*".equals(getColumnName(columnName))) { 9150 continue; 9151 } 9152 resultColumn.bindStarLinkColumn(columnName); 9153 } 9154 } else { 9155 TTableList tables = stmt.getTables(); 9156 for (int k = 0; k < tables.size(); k++) { 9157 TTable tableElement = tables.getTable(k); 9158 TObjectName[] columns = modelManager.getTableColumns(tableElement); 9159 for (int j = 0; j < columns.length; j++) { 9160 TObjectName columnName = columns[j]; 9161 if (columnName == null || "*".equals(getColumnName(columnName))) { 9162 continue; 9163 } 9164 resultColumn.bindStarLinkColumn(columnName); 9165 } 9166 } 9167 } 9168 } 9169 9170 if ("*".equals(getColumnName(tableColumn.getColumnObject())) && resultColumn != null 9171 && !resultColumn.getStarLinkColumns().isEmpty()) { 9172 tableColumn.bindStarLinkColumns(resultColumn.getStarLinkColumns()); 9173 } 9174 9175 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9176 relation.setEffectType(effectType); 9177 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9178 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9179 9180 if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) { 9181 tableColumn.getTable().setStarStmt("insert"); 9182 } 9183 9184 Process process = modelFactory.createProcess(stmt); 9185 relation.setProcess(process); 9186 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 9187 .getExpressionType() == EExpressionType.simple_constant_t) { 9188 if (!initColumn) { 9189 TableColumn tableColumn; 9190 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9191 if (tableModel.getColumns().size() <= i) { 9192 continue; 9193 } 9194 tableColumn = tableModel.getColumns().get(i); 9195 } else { 9196 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9197 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 9198 .getConstantOperand(), 9199 i); 9200 } 9201 9202 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 9203 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 9204 TSQLSchema schema = sqlenv.getSQLSchema( 9205 tableModel.getDatabase() + "." + tableModel.getSchema(), true); 9206 if (schema != null) { 9207 TSQLTable tempTable = schema.createTable( 9208 DlineageUtil.getSimpleTableName(tableModel.getName())); 9209 tempTable.addColumn(tableColumn.getName()); 9210 } 9211 } 9212 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9213 relation.setEffectType(effectType); 9214 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9215 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9216 Process process = modelFactory.createProcess(stmt); 9217 relation.setProcess(process); 9218 } else { 9219 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9220 relation.setEffectType(effectType); 9221 relation.setTarget( 9222 new TableColumnRelationshipElement(tableModel.getColumns().get(i))); 9223 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9224 Process process = modelFactory.createProcess(stmt); 9225 relation.setProcess(process); 9226 } 9227 } else { 9228 if (!initColumn) { 9229 TableColumn tableColumn; 9230 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9231 if (tableModel.getColumns().size() <= i) { 9232 continue; 9233 } 9234 tableColumn = tableModel.getColumns().get(i); 9235 } else { 9236 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9237 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i); 9238 } 9239 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 9240 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 9241 TSQLSchema schema = sqlenv.getSQLSchema( 9242 tableModel.getDatabase() + "." + tableModel.getSchema(), true); 9243 if (schema != null) { 9244 TSQLTable tempTable = schema.createTable( 9245 DlineageUtil.getSimpleTableName(tableModel.getName())); 9246 tempTable.addColumn(tableColumn.getName()); 9247 } 9248 } 9249 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9250 relation.setEffectType(effectType); 9251 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9252 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9253 Process process = modelFactory.createProcess(stmt); 9254 relation.setProcess(process); 9255 } else { 9256 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9257 relation.setEffectType(effectType); 9258 relation.setTarget( 9259 new TableColumnRelationshipElement(tableModel.getColumns().get(i))); 9260 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9261 Process process = modelFactory.createProcess(stmt); 9262 relation.setProcess(process); 9263 } 9264 } 9265 } 9266 } 9267 } else if (stmt.getSubQuery() != null) { 9268 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 9269 if (resultSetModel != null) { 9270 9271 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 9272 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 9273 impactRelation.setEffectType(effectType); 9274 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 9275 resultSetModel.getRelationRows())); 9276 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 9277 tableModel.getRelationRows())); 9278 } 9279 9280 if(stmt.getColumnList()!=null && stmt.getColumnList().size()>0) { 9281 for(int i=0;i<stmt.getColumnList().size();i++) { 9282 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9283 stmt.getColumnList().getObjectName(i)); 9284 } 9285 9286 List<TableColumn> columns = tableModel.getColumns(); 9287 int resultSetSize = resultSetModel.getColumns().size(); 9288 int starIndex = 0; 9289 int j = 0; 9290 boolean fromStruct = false; 9291 for (int i = 0; i < columns.size() && j < resultSetSize; i++) { 9292 String column = columns.get(i).getName(); 9293 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 9294 if (!resultColumn.getName().contains("*")) { 9295 if (resultColumn.getName().equals(resultColumn.getRefColumnName()) 9296 && resultColumn.getColumnObject().toString().endsWith("*") 9297 && resultSetSize == 1) { 9298 starIndex++; 9299 if (resultSetSize - j == columns.size() - i) { 9300 j++; 9301 9302 } 9303 } 9304 else { 9305 j++; 9306 } 9307 } else { 9308 starIndex++; 9309 if (resultSetSize - j == columns.size() - i) { 9310 j++; 9311 9312 } 9313 } 9314 if (column != null) { 9315 TableColumn tableColumn; 9316 // if (!initColumn) { 9317 tableColumn = matchColumn(tableModel.getColumns(), columns.get(i)); 9318 if (tableColumn == null) { 9319 if (tableModel.isCreateTable() 9320 && !containStarColumn(tableModel.getColumns())) { 9321 if (tableModel.getColumns().size() <= i) { 9322 continue; 9323 } 9324 tableColumn = tableModel.getColumns().get(i); 9325 } else { 9326 TObjectName columnName = new TObjectName(); 9327 columnName.setString(column); 9328 tableColumn = modelFactory.createTableColumn(tableModel, columnName, 9329 false); 9330 } 9331 } 9332 else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) { 9333 j--; 9334 fromStruct = true; 9335 } 9336 if(fromStruct && !tableColumn.isStruct()) { 9337 fromStruct = false; 9338 resultColumn = resultSetModel.getColumns().get(j); 9339 j++; 9340 } 9341 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9342 relation.setEffectType(effectType); 9343 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9344 if (resultColumn.hasStarLinkColumn() 9345 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 9346 ResultColumn expandStarColumn = modelFactory.createResultColumn( 9347 resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1), 9348 false); 9349 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 9350 } else { 9351 relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1)); 9352 } 9353 Process process = modelFactory.createProcess(stmt); 9354 relation.setProcess(process); 9355 } 9356 } 9357 } 9358 else { 9359 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 9360 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 9361 TAliasClause alias = null; 9362 if(resultColumn.getColumnObject() instanceof TResultColumn) { 9363 alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause(); 9364 } 9365 if (stmt.getColumnList() != null) { 9366 if (i < stmt.getColumnList().size()) { 9367 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9368 relation.setEffectType(effectType); 9369 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9370 stmt.getColumnList().getObjectName(i)); 9371 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9372 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9373 Process process = modelFactory.createProcess(stmt); 9374 relation.setProcess(process); 9375 } 9376 } else { 9377 if (alias != null && alias.getAliasName() != null) { 9378 TableColumn tableColumn; 9379 if (!initColumn) { 9380 if (tableModel.isCreateTable() 9381 && !containStarColumn(tableModel.getColumns())) { 9382 if (tableModel.getColumns().size() <= i) { 9383 continue; 9384 } 9385 tableColumn = tableModel.getColumns().get(i); 9386 } else { 9387 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9388 alias.getAliasName()); 9389 } 9390 } else { 9391 tableColumn = matchColumn(tableColumns, alias.getAliasName()); 9392 if (tableColumn == null) { 9393 continue; 9394 } 9395 } 9396 9397 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9398 relation.setEffectType(effectType); 9399 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9400 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9401 Process process = modelFactory.createProcess(stmt); 9402 relation.setProcess(process); 9403 } else if (resultColumn.getColumnObject() instanceof TObjectName 9404 || ( resultColumn.getColumnObject() instanceof TResultColumn && ((TResultColumn) resultColumn.getColumnObject()) 9405 .getFieldAttr() != null)) { 9406 TObjectName fieldAttr = null; 9407 if (resultColumn.getColumnObject() instanceof TObjectName) { 9408 fieldAttr = (TObjectName)resultColumn.getColumnObject(); 9409 } 9410 else if (resultColumn.getColumnObject() instanceof TResultColumn) { 9411 fieldAttr = ((TResultColumn) resultColumn.getColumnObject()) 9412 .getFieldAttr(); 9413 } 9414 9415 TableColumn tableColumn; 9416 if (!initColumn) { 9417 if (tableModel.isCreateTable() 9418 && !containStarColumn(tableModel.getColumns())) { 9419 if (tableModel.getColumns().size() <= i) { 9420 continue; 9421 } 9422 tableColumn = tableModel.getColumns().get(i); 9423 } else { 9424 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9425 fieldAttr); 9426 } 9427 } else { 9428 tableColumn = matchColumn(tableColumns, fieldAttr); 9429 if (tableColumn == null) { 9430 continue; 9431 } 9432 } 9433 9434 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9435 relation.setEffectType(effectType); 9436 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9437 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9438 Process process = modelFactory.createProcess(stmt); 9439 relation.setProcess(process); 9440 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 9441 .getExpressionType() == EExpressionType.simple_constant_t) { 9442 if (!initColumn) { 9443 TableColumn tableColumn; 9444 if (tableModel.isCreateTable() 9445 && !containStarColumn(tableModel.getColumns())) { 9446 if (tableModel.getColumns().size() <= i) { 9447 continue; 9448 } 9449 tableColumn = tableModel.getColumns().get(i); 9450 } else { 9451 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9452 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 9453 .getConstantOperand(), 9454 i); 9455 } 9456 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9457 relation.setEffectType(effectType); 9458 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9459 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9460 Process process = modelFactory.createProcess(stmt); 9461 relation.setProcess(process); 9462 } 9463 } else { 9464 if (!initColumn) { 9465 TableColumn tableColumn; 9466 if (tableModel.isCreateTable() 9467 && !containStarColumn(tableModel.getColumns())) { 9468 if (tableModel.getColumns().size() <= i) { 9469 continue; 9470 } 9471 tableColumn = tableModel.getColumns().get(i); 9472 } else { 9473 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9474 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i); 9475 } 9476 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9477 relation.setEffectType(effectType); 9478 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9479 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9480 Process process = modelFactory.createProcess(stmt); 9481 relation.setProcess(process); 9482 } 9483 } 9484 } 9485 } 9486 } 9487 } 9488 } 9489 } 9490 } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) { 9491 TObjectNameList items = stmt.getColumnList(); 9492 TMultiTargetList values = stmt.getValues(); 9493 if (values != null) { 9494 for (int k = 0; values != null && k < values.size(); k++) { 9495 int j = 0; 9496 for (int i = 0; i < items.size(); i++) { 9497 TObjectName column = items.getObjectName(i); 9498 TableColumn tableColumn; 9499 if (!initColumn) { 9500 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9501 if (tableModel.getColumns().size() <= i) { 9502 continue; 9503 } 9504 tableColumn = tableModel.getColumns().get(i); 9505 } else { 9506 tableColumn = modelFactory.createInsertTableColumn(tableModel, column); 9507 } 9508 } else { 9509 tableColumn = matchColumn(tableColumns, column); 9510 if (tableColumn == null) { 9511 continue; 9512 } 9513 } 9514 TResultColumn columnObject = values.getMultiTarget(k).getColumnList().getResultColumn(j); 9515 if (columnObject == null) { 9516 continue; 9517 } 9518 TExpression valueExpr = columnObject.getExpr(); 9519 columnsInExpr visitor = new columnsInExpr(); 9520 valueExpr.inOrderTraverse(visitor); 9521 List<TObjectName> objectNames = visitor.getObjectNames(); 9522 List<TParseTreeNode> constants = visitor.getConstants(); 9523 List<TParseTreeNode> functions = visitor.getFunctions(); 9524 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 9525 9526 Process process = modelFactory.createProcess(stmt); 9527 9528 9529 9530 if (functions != null && !functions.isEmpty()) { 9531 analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process); 9532 } 9533 9534 if (subquerys != null && !subquerys.isEmpty()) { 9535 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process); 9536 } 9537 if (objectNames != null && !objectNames.isEmpty()) { 9538 analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions, 9539 process, i); 9540 } 9541 //insert into values generate too many constant relations, ignore constant relations. 9542 if (constants != null && !constants.isEmpty()) { 9543 if (!option.isIgnoreInsertIntoValues() || stmt.getParentStmt() != null) { 9544 analyzeConstantDataFlowRelation(tableColumn, constants, effectType, 9545 functions, process); 9546 } 9547 } 9548 j++; 9549 } 9550 } 9551 } else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) { 9552 analyzeCustomSqlStmt(stmt.getExecuteStmt()); 9553 Procedure procedure = modelManager.getProcedureByName(DlineageUtil 9554 .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString())); 9555 if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) { 9556 TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure 9557 .getProcedureObject(); 9558 List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt); 9559 if (stmtItems != null) { 9560 for(TSelectSqlStatement stmtItem: stmtItems) { 9561 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem); 9562 if (resultSetModel != null) { 9563 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 9564 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 9565 Transform transform = new Transform(); 9566 transform.setType(Transform.FUNCTION); 9567 transform.setCode(stmt.getExecuteStmt().getModuleName()); 9568 resultColumn.setTransform(transform); 9569 9570 if (stmt.getColumnList() != null) { 9571 if (i < stmt.getColumnList().size()) { 9572 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9573 relation.setEffectType(effectType); 9574 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9575 stmt.getColumnList().getObjectName(i)); 9576 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9577 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9578 Process process = modelFactory.createProcess(stmt); 9579 relation.setProcess(process); 9580 } 9581 } else { 9582 if (resultColumn.getColumnObject() instanceof TObjectName) { 9583 TObjectName fieldAttr = ((TObjectName) resultColumn.getColumnObject()); 9584 TableColumn tableColumn; 9585 if (!initColumn) { 9586 if (tableModel.isCreateTable() 9587 && !containStarColumn(tableModel.getColumns())) { 9588 if (tableModel.getColumns().size() <= i) { 9589 continue; 9590 } 9591 tableColumn = tableModel.getColumns().get(i); 9592 } else { 9593 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9594 fieldAttr); 9595 } 9596 } else { 9597 tableColumn = matchColumn(tableColumns, fieldAttr); 9598 if (tableColumn == null) { 9599 continue; 9600 } 9601 } 9602 9603 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9604 relation.setEffectType(effectType); 9605 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9606 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9607 Process process = modelFactory.createProcess(stmt); 9608 relation.setProcess(process); 9609 9610 9611 } else { 9612 TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()) 9613 .getAliasClause(); 9614 if (alias != null && alias.getAliasName() != null) { 9615 TableColumn tableColumn; 9616 if (!initColumn) { 9617 if (tableModel.isCreateTable() 9618 && !containStarColumn(tableModel.getColumns())) { 9619 if (tableModel.getColumns().size() <= i) { 9620 continue; 9621 } 9622 tableColumn = tableModel.getColumns().get(i); 9623 } else { 9624 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9625 alias.getAliasName()); 9626 } 9627 } else { 9628 tableColumn = matchColumn(tableColumns, alias.getAliasName()); 9629 if (tableColumn == null) { 9630 continue; 9631 } 9632 } 9633 9634 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9635 relation.setEffectType(effectType); 9636 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9637 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9638 Process process = modelFactory.createProcess(stmt); 9639 relation.setProcess(process); 9640 } else if (((TResultColumn) resultColumn.getColumnObject()) 9641 .getFieldAttr() != null) { 9642 TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject()) 9643 .getFieldAttr(); 9644 TableColumn tableColumn; 9645 if (!initColumn) { 9646 if (tableModel.isCreateTable() 9647 && !containStarColumn(tableModel.getColumns())) { 9648 if (tableModel.getColumns().size() <= i) { 9649 continue; 9650 } 9651 tableColumn = tableModel.getColumns().get(i); 9652 } else { 9653 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9654 fieldAttr); 9655 } 9656 } else { 9657 tableColumn = matchColumn(tableColumns, fieldAttr); 9658 if (tableColumn == null) { 9659 continue; 9660 } 9661 } 9662 9663 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9664 relation.setEffectType(effectType); 9665 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9666 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9667 Process process = modelFactory.createProcess(stmt); 9668 relation.setProcess(process); 9669 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 9670 .getExpressionType() == EExpressionType.simple_constant_t) { 9671 if (!initColumn) { 9672 TableColumn tableColumn; 9673 if (tableModel.isCreateTable() 9674 && !containStarColumn(tableModel.getColumns())) { 9675 if (tableModel.getColumns().size() <= i) { 9676 continue; 9677 } 9678 tableColumn = tableModel.getColumns().get(i); 9679 } else { 9680 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9681 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 9682 .getConstantOperand(), 9683 i); 9684 } 9685 9686 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9687 relation.setEffectType(effectType); 9688 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9689 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9690 Process process = modelFactory.createProcess(stmt); 9691 relation.setProcess(process); 9692 } 9693 } else { 9694 if (!initColumn) { 9695 TableColumn tableColumn; 9696 if (tableModel.isCreateTable() 9697 && !containStarColumn(tableModel.getColumns())) { 9698 if (tableModel.getColumns().size() <= i) { 9699 continue; 9700 } 9701 tableColumn = tableModel.getColumns().get(i); 9702 } else { 9703 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9704 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), 9705 i); 9706 } 9707 9708 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9709 relation.setEffectType(effectType); 9710 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9711 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9712 Process process = modelFactory.createProcess(stmt); 9713 relation.setProcess(process); 9714 } 9715 } 9716 } 9717 } 9718 } 9719 } 9720 } 9721 } 9722 } 9723 else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) { 9724 TObjectName functionName = new TObjectName(); 9725 functionName.setString(procedure.getName()); 9726 Function function = (Function)createFunction(functionName); 9727 if (stmt.getColumnList() != null) { 9728 for (int i = 0; i < stmt.getColumnList().size(); i++) { 9729 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9730 relation.setEffectType(effectType); 9731 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9732 stmt.getColumnList().getObjectName(i)); 9733 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9734 relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0))); 9735 Process process = modelFactory.createProcess(stmt); 9736 relation.setProcess(process); 9737 } 9738 } 9739 } 9740 } 9741 } else if (stmt.getValues() != null && stmt.getValues().size() > 0 && tableModel.isCreateTable() && !tableModel.getColumns().isEmpty()) { 9742 for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) { 9743 TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList(); 9744 boolean allConstant = true; 9745 Process process = modelFactory.createProcess(stmt); 9746 for (int x = 0; x < columns.size(); x++) { 9747 TableColumn tableColumn = tableModel.getColumns().get(x); 9748 TResultColumn columnObject = columns.getResultColumn(x); 9749 if (columnObject == null) { 9750 continue; 9751 } 9752 TExpression valueExpr = columnObject.getExpr(); 9753 columnsInExpr visitor = new columnsInExpr(); 9754 valueExpr.inOrderTraverse(visitor); 9755 List<TObjectName> objectNames = visitor.getObjectNames(); 9756 List<TParseTreeNode> constants = visitor.getConstants(); 9757 List<TParseTreeNode> functions = visitor.getFunctions(); 9758 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 9759 9760 if (functions != null && !functions.isEmpty()) { 9761 analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process); 9762 allConstant = false; 9763 } 9764 9765 if (subquerys != null && !subquerys.isEmpty()) { 9766 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process); 9767 allConstant = false; 9768 } 9769 if (objectNames != null && !objectNames.isEmpty()) { 9770 analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions, 9771 process); 9772 allConstant = false; 9773 } 9774 //insert into values generate too many constant relations, ignore constant relations. 9775 if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) { 9776 analyzeConstantDataFlowRelation(tableColumn, constants, effectType, functions, 9777 process); 9778 allConstant = false; 9779 } 9780 } 9781 9782 if(allConstant) { 9783 modelManager.unbindProcessModel(stmt); 9784 tableModel.removeProcess(process); 9785 } 9786 } 9787 } else if (stmt.getRecordName() != null) { 9788 String procedureName = DlineageUtil.getProcedureParentName(stmt); 9789 String variableString = stmt.getRecordName().toString(); 9790 if (variableString.startsWith(":")) { 9791 variableString = variableString.substring(variableString.indexOf(":") + 1); 9792 } 9793 if (!SQLUtil.isEmpty(procedureName)) { 9794 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 9795 } 9796 9797 Table recordTable = modelManager 9798 .getTableByName(DlineageUtil.getTableFullName(variableString)); 9799 if (recordTable != null) { 9800 for (int i = 0; i < recordTable.getColumns().size(); i++) { 9801 TableColumn sourceTableColumn = recordTable.getColumns().get(i); 9802 TableColumn targetTableColumn = modelFactory.createTableColumn(tableModel, 9803 sourceTableColumn.getColumnObject(), false); 9804 if (targetTableColumn != null) { 9805 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9806 relation.setEffectType(effectType); 9807 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 9808 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 9809 Process process = modelFactory.createProcess(stmt); 9810 relation.setProcess(process); 9811 } else if (sourceTableColumn.getName().endsWith("*") && tableModel.isCreateTable()) { 9812 for (TableColumn column : tableModel.getColumns()) { 9813 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9814 relation.setEffectType(effectType); 9815 relation.setTarget(new TableColumnRelationshipElement(column)); 9816 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 9817 Process process = modelFactory.createProcess(stmt); 9818 relation.setProcess(process); 9819 } 9820 } 9821 } 9822 } 9823 } else if (stmt.getInsertSource() == EInsertSource.values_function && stmt.getFunctionCall() != null) { 9824 Table cursor = modelManager.getTableByName( 9825 DlineageUtil.getTableFullName(stmt.getFunctionCall().getFunctionName().toString())); 9826 if (cursor != null) { 9827 TObjectName starColumn = new TObjectName(); 9828 starColumn.setString("*"); 9829 TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 9830 insertColumn.setShowStar(false); 9831 insertColumn.setExpandStar(true); 9832 for (int j = 0; j < cursor.getColumns().size(); j++) { 9833 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 9834 dataflowRelation.setEffectType(effectType); 9835 dataflowRelation.addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j))); 9836 dataflowRelation.setTarget(new TableColumnRelationshipElement(insertColumn)); 9837 Process process = modelFactory.createProcess(stmt); 9838 dataflowRelation.setProcess(process); 9839 } 9840 } 9841 9842 } else if (stmt.getInsertSource() == EInsertSource.values && stmt.getValues() != null) { 9843 TObjectName starColumn = new TObjectName(); 9844 starColumn.setString("*"); 9845 TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 9846 insertColumn.setShowStar(false); 9847 insertColumn.setExpandStar(true); 9848 for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) { 9849 TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList(); 9850 for (int x = 0; x < columns.size(); x++) { 9851 TResultColumn columnObject = columns.getResultColumn(x); 9852 if (columnObject == null) { 9853 continue; 9854 } 9855 TExpression valueExpr = columnObject.getExpr(); 9856 columnsInExpr visitor = new columnsInExpr(); 9857 valueExpr.inOrderTraverse(visitor); 9858 List<TObjectName> objectNames = visitor.getObjectNames(); 9859 List<TParseTreeNode> constants = visitor.getConstants(); 9860 List<TParseTreeNode> functions = visitor.getFunctions(); 9861 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 9862 9863 Process process = modelFactory.createProcess(stmt); 9864 if (functions != null && !functions.isEmpty()) { 9865 analyzeFunctionDataFlowRelation(insertColumn, functions, effectType, process); 9866 } 9867 9868 if (subquerys != null && !subquerys.isEmpty()) { 9869 analyzeSubqueryDataFlowRelation(insertColumn, subquerys, effectType, process); 9870 } 9871 if (objectNames != null && !objectNames.isEmpty()) { 9872 analyzeDataFlowRelation(insertColumn, objectNames, null, effectType, functions, 9873 process); 9874 } 9875 //insert into values generate too many constant relations, ignore constant relations. 9876 if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) { 9877 analyzeConstantDataFlowRelation(insertColumn, constants, effectType, functions, 9878 process); 9879 } 9880 } 9881 } 9882 }else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) { 9883 analyzeCustomSqlStmt(stmt.getExecuteStmt()); 9884 Procedure procedure = modelManager.getProcedureByName(DlineageUtil 9885 .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString())); 9886 if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) { 9887 TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure 9888 .getProcedureObject(); 9889 List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt); 9890 if (stmtItems != null) { 9891 for(TSelectSqlStatement stmtItem: stmtItems) { 9892 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem); 9893 if (resultSetModel != null) { 9894 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 9895 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 9896 9897 Transform transform = new Transform(); 9898 transform.setType(Transform.FUNCTION); 9899 transform.setCode(stmt.getExecuteStmt().getModuleName()); 9900 resultColumn.setTransform(transform); 9901 9902 TAliasClause alias = null; 9903 9904 if (resultColumn.getColumnObject() instanceof TResultColumn) { 9905 alias = ((TResultColumn) resultColumn.getColumnObject()) 9906 .getAliasClause(); 9907 } 9908 9909 if (alias != null && alias.getAliasName() != null) { 9910 TableColumn tableColumn; 9911 if (!initColumn) { 9912 if (tableModel.isCreateTable() 9913 && !containStarColumn(tableModel.getColumns())) { 9914 if(resultColumn.getName().endsWith("*")) { 9915 for(TableColumn tableColumnItem: tableModel.getColumns()) { 9916 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9917 relation.setEffectType(effectType); 9918 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 9919 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9920 Process process = modelFactory.createProcess(stmt); 9921 relation.setProcess(process); 9922 } 9923 continue; 9924 } 9925 else { 9926 if (tableModel.getColumns().size() <= i) { 9927 continue; 9928 } 9929 tableColumn = tableModel.getColumns().get(i); 9930 } 9931 } else { 9932 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9933 alias.getAliasName()); 9934 } 9935 } else { 9936 tableColumn = matchColumn(tableColumns, alias.getAliasName()); 9937 if (tableColumn == null) { 9938 continue; 9939 } 9940 } 9941 9942 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9943 relation.setEffectType(effectType); 9944 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9945 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9946 Process process = modelFactory.createProcess(stmt); 9947 relation.setProcess(process); 9948 } else if (resultColumn.getColumnObject() instanceof TObjectName 9949 || (resultColumn.getColumnObject() instanceof TResultColumn 9950 && ((TResultColumn) resultColumn.getColumnObject()) 9951 .getFieldAttr() != null)) { 9952 TObjectName fieldAttr = null; 9953 if (resultColumn.getColumnObject() instanceof TObjectName) { 9954 fieldAttr = (TObjectName) resultColumn.getColumnObject(); 9955 } else { 9956 fieldAttr = ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(); 9957 } 9958 TableColumn tableColumn; 9959 if (!initColumn) { 9960 if (tableModel.isCreateTable() 9961 && !containStarColumn(tableModel.getColumns())) { 9962 if(resultColumn.getName().endsWith("*")) { 9963 for(TableColumn tableColumnItem: tableModel.getColumns()) { 9964 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9965 relation.setEffectType(effectType); 9966 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 9967 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9968 Process process = modelFactory.createProcess(stmt); 9969 relation.setProcess(process); 9970 } 9971 continue; 9972 } 9973 else { 9974 if (tableModel.getColumns().size() <= i) { 9975 continue; 9976 } 9977 tableColumn = tableModel.getColumns().get(i); 9978 } 9979 } else { 9980 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9981 fieldAttr); 9982 } 9983 } else { 9984 tableColumn = matchColumn(tableColumns, fieldAttr); 9985 if (tableColumn == null) { 9986 continue; 9987 } 9988 } 9989 9990 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9991 relation.setEffectType(effectType); 9992 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9993 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9994 Process process = modelFactory.createProcess(stmt); 9995 relation.setProcess(process); 9996 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 9997 .getExpressionType() == EExpressionType.simple_constant_t) { 9998 if (!initColumn) { 9999 TableColumn tableColumn; 10000 if (tableModel.isCreateTable() 10001 && !containStarColumn(tableModel.getColumns())) { 10002 if(resultColumn.getName().endsWith("*")) { 10003 for(TableColumn tableColumnItem: tableModel.getColumns()) { 10004 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10005 relation.setEffectType(effectType); 10006 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 10007 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10008 Process process = modelFactory.createProcess(stmt); 10009 relation.setProcess(process); 10010 } 10011 continue; 10012 } 10013 else { 10014 if (tableModel.getColumns().size() <= i) { 10015 continue; 10016 } 10017 tableColumn = tableModel.getColumns().get(i); 10018 } 10019 } else { 10020 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10021 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 10022 .getConstantOperand(), 10023 i); 10024 } 10025 10026 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10027 relation.setEffectType(effectType); 10028 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10029 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10030 Process process = modelFactory.createProcess(stmt); 10031 relation.setProcess(process); 10032 } 10033 } else { 10034 if (!initColumn) { 10035 TableColumn tableColumn; 10036 if (tableModel.isCreateTable() 10037 && !containStarColumn(tableModel.getColumns())) { 10038 if(resultColumn.getName().endsWith("*")) { 10039 for(TableColumn tableColumnItem: tableModel.getColumns()) { 10040 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10041 relation.setEffectType(effectType); 10042 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 10043 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10044 Process process = modelFactory.createProcess(stmt); 10045 relation.setProcess(process); 10046 } 10047 continue; 10048 } 10049 else { 10050 if (tableModel.getColumns().size() <= i) { 10051 continue; 10052 } 10053 tableColumn = tableModel.getColumns().get(i); 10054 } 10055 } else { 10056 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10057 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), 10058 i); 10059 } 10060 10061 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10062 relation.setEffectType(effectType); 10063 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10064 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10065 Process process = modelFactory.createProcess(stmt); 10066 relation.setProcess(process); 10067 } 10068 } 10069 } 10070 } 10071 } 10072 } 10073 } 10074 else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) { 10075 TObjectName functionName = new TObjectName(); 10076 functionName.setString(procedure.getName()); 10077 Function function = (Function)createFunction(functionName); 10078 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10079 relation.setEffectType(effectType); 10080 TObjectName starColumn = new TObjectName(); 10081 starColumn.setString("*"); 10082 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 10083 starColumn); 10084 tableColumn.setExpandStar(false); 10085 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10086 relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0))); 10087 Process process = modelFactory.createProcess(stmt); 10088 relation.setProcess(process); 10089 } 10090 } 10091 } 10092 10093 if(stmt.getOnDuplicateKeyUpdate()!=null) { 10094 TTable table = stmt.getTargetTable(); 10095 Table tableModel = modelFactory.createTable(table); 10096 for(TResultColumn column: stmt.getOnDuplicateKeyUpdate()) { 10097 if(column.getExpr()==null || column.getExpr().getExpressionType() != EExpressionType.assignment_t) { 10098 continue; 10099 } 10100 TExpression left = column.getExpr().getLeftOperand(); 10101 TExpression right = column.getExpr().getRightOperand(); 10102 TObjectName columnObject = left.getObjectOperand(); 10103 if (columnObject != null) { 10104 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false); 10105 if (tableColumn != null) { 10106 columnsInExpr visitor = new columnsInExpr(); 10107 right.inOrderTraverse(visitor); 10108 List<TObjectName> objectNames = visitor.getObjectNames(); 10109 List<TParseTreeNode> functions = visitor.getFunctions(); 10110 List<TParseTreeNode> constants = visitor.getConstants(); 10111 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 10112 10113 if (functions != null && !functions.isEmpty()) { 10114 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.update); 10115 } 10116 if (subquerys != null && !subquerys.isEmpty()) { 10117 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.update); 10118 } 10119 if (objectNames != null && !objectNames.isEmpty()) { 10120 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.update, functions); 10121 } 10122 if (constants != null && !constants.isEmpty()) { 10123 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.update, functions); 10124 } 10125 } 10126 } 10127 } 10128 } 10129 10130 if (!expressions.isEmpty() && stmt.getSubQuery() != null) { 10131 analyzeInsertImpactRelation(stmt.getSubQuery(), tableColumnMap, expressions, effectType); 10132 } 10133 } 10134 10135 private List<TSelectSqlStatement> getLastSelectStmt(TStoredProcedureSqlStatement procedureStmt) { 10136 List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>(); 10137 if (procedureStmt.getBodyStatements().size() > 0) { 10138 for (int j = procedureStmt.getBodyStatements().size() - 1; j >= 0; j--) { 10139 TCustomSqlStatement stmtItem = procedureStmt.getBodyStatements().get(j); 10140 if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) { 10141 if (stmtItem.getStatements() != null) { 10142 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10143 if (item != null && !item.isEmpty()) { 10144 stmts.addAll(item); 10145 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10146 break; 10147 } 10148 } 10149 } 10150 break; 10151 } 10152 if (stmtItem instanceof TSelectSqlStatement) { 10153 stmts.add((TSelectSqlStatement) stmtItem); 10154 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10155 break; 10156 } 10157 } else if (stmtItem.getStatements() != null) { 10158 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10159 if (item != null && !item.isEmpty()) { 10160 stmts.addAll(item); 10161 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10162 break; 10163 } 10164 } 10165 } 10166 } 10167 } 10168 return stmts; 10169 } 10170 10171 private List<TSelectSqlStatement> getLastSelectStmt(TCustomSqlStatement stmt) { 10172 List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>(); 10173 for (int j = stmt.getStatements().size() - 1; j >= 0; j--) { 10174 TCustomSqlStatement stmtItem = stmt.getStatements().get(j); 10175 if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) { 10176 if (stmtItem.getStatements() != null) { 10177 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10178 if (item != null && !item.isEmpty()) { 10179 stmts.addAll(item); 10180 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10181 break; 10182 } 10183 } 10184 } 10185 break; 10186 } 10187 if (stmtItem instanceof TSelectSqlStatement) { 10188 stmts.add((TSelectSqlStatement) stmtItem); 10189 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10190 break; 10191 } 10192 } else if (stmtItem.getStatements() != null) { 10193 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10194 if (item != null && !item.isEmpty()) { 10195 stmts.addAll(item); 10196 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10197 break; 10198 } 10199 } 10200 } 10201 } 10202 return stmts; 10203 } 10204 10205 private TableColumn getStarColumn(List<TableColumn> columns) { 10206 for (TableColumn column : columns) { 10207 if (column.getName().endsWith("*")) { 10208 return column; 10209 } 10210 } 10211 return null; 10212 } 10213 10214 private boolean containStarColumn(List<TableColumn> columns) { 10215 if (columns == null) 10216 return false; 10217 for (TableColumn column : columns) { 10218 if (column.getName().endsWith("*")) { 10219 return true; 10220 } 10221 } 10222 return false; 10223 } 10224 10225 private boolean containStarColumn(ResultSet resultSet) { 10226 if (resultSet == null || resultSet.getColumns() == null) 10227 return false; 10228 for (ResultColumn column : resultSet.getColumns()) { 10229 if (column.getName().endsWith("*")) { 10230 return true; 10231 } 10232 } 10233 return false; 10234 } 10235 10236 private int indexOfColumn(List<TResultColumn> columns, TObjectName objectName) { 10237 for (int i = 0; i < columns.size(); i++) { 10238 if (columns.get(i).toString().trim().equalsIgnoreCase(objectName.toString().trim())) { 10239 return i; 10240 } 10241 } 10242 return -1; 10243 } 10244 10245 private boolean isEmptyCollection(Collection<?> keyMap) { 10246 return keyMap == null || keyMap.isEmpty(); 10247 } 10248 10249 private void analyzeInsertImpactRelation(TSelectSqlStatement stmt, Map<String, List<TableColumn>> insertMap, 10250 List<TExpression> expressions, EffectType effectType) { 10251 List<TObjectName> objectNames = new ArrayList<TObjectName>(); 10252 for (int i = 0; i < expressions.size(); i++) { 10253 TExpression condition = expressions.get(i); 10254 columnsInExpr visitor = new columnsInExpr(); 10255 condition.inOrderTraverse(visitor); 10256 objectNames.addAll(visitor.getObjectNames()); 10257 } 10258 10259 Iterator<String> iter = insertMap.keySet().iterator(); 10260 while (iter.hasNext()) { 10261 String table = iter.next(); 10262 List<TableColumn> tableColumns = insertMap.get(table); 10263 for (int i = 0; i < tableColumns.size(); i++) { 10264 10265 TableColumn column = tableColumns.get(i); 10266 ImpactRelationship relation = modelFactory.createImpactRelation(); 10267 relation.setEffectType(effectType); 10268 relation.setTarget(new TableColumnRelationshipElement(column)); 10269 10270 for (int j = 0; j < objectNames.size(); j++) { 10271 TObjectName columnName = objectNames.get(j); 10272 Object model = modelManager.getModel(stmt); 10273 if (model instanceof SelectResultSet) { 10274 SelectResultSet queryTable = (SelectResultSet) model; 10275 List<ResultColumn> columns = queryTable.getColumns(); 10276 for (int k = 0; k < columns.size(); k++) { 10277 ResultColumn resultColumn = columns.get(k); 10278 if (resultColumn.getAlias() != null 10279 && columnName.toString().equalsIgnoreCase(resultColumn.getAlias())) { 10280 relation.addSource( 10281 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 10282 } else if (resultColumn.getName() != null 10283 && columnName.toString().equalsIgnoreCase(resultColumn.getName())) { 10284 relation.addSource( 10285 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 10286 } 10287 } 10288 } 10289 } 10290 } 10291 } 10292 } 10293 10294 private void analyzeUpdateStmt(TUpdateSqlStatement stmt) { 10295 if (stmt.getResultColumnList() == null) 10296 return; 10297 10298 TTable table = stmt.getTargetTable(); 10299 while (table.getCTE() != null || table.getSubquery() != null || (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null)) { 10300 if (table.getCTE() != null) { 10301 table = table.getCTE().getSubquery().getTables().getTable(0); 10302 } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) { 10303 table = table.getLinkTable().getSubquery().getTables().getTable(0); 10304 } else if (table.getSubquery() != null) { 10305 table = table.getSubquery().getTables().getTable(0); 10306 } 10307 } 10308 Table tableModel = modelFactory.createTable(table); 10309 Process process = modelFactory.createProcess(stmt); 10310 tableModel.addProcess(process); 10311 10312 for (int i = 0; i < stmt.tables.size(); i++) { 10313 TTable tableElement = stmt.tables.getTable(i); 10314 if (tableElement.getSubquery() != null) { 10315 QueryTable queryTable = modelFactory.createQueryTable(tableElement); 10316 TSelectSqlStatement subquery = tableElement.getSubquery(); 10317 analyzeSelectStmt(subquery); 10318 10319 if (subquery.getSetOperatorType() != ESetOperatorType.none) { 10320 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager.getModel(subquery); 10321 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 10322 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 10323 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 10324 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 10325 selectSetRalation.setEffectType(EffectType.select); 10326 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 10327 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 10328 selectSetRalation.setProcess(process); 10329 } 10330 } 10331 10332 ResultSet resultSetModel = (ResultSet) modelManager.getModel(tableElement.getSubquery()); 10333 if (resultSetModel != null && resultSetModel != queryTable 10334 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 10335 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 10336 impactRelation.setEffectType(EffectType.update); 10337 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 10338 resultSetModel.getRelationRows())); 10339 impactRelation.setTarget( 10340 new RelationRowsRelationshipElement<ResultSetRelationRows>(queryTable.getRelationRows())); 10341 } 10342 10343 } else if (tableElement.getCTE() != null) { 10344 QueryTable queryTable = modelFactory.createQueryTable(tableElement); 10345 10346 TObjectNameList cteColumns = tableElement.getCTE().getColumnList(); 10347 if (cteColumns != null) { 10348 for (int j = 0; j < cteColumns.size(); j++) { 10349 modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j)); 10350 } 10351 } 10352 TSelectSqlStatement subquery = tableElement.getCTE().getSubquery(); 10353 if (subquery != null && !stmtStack.contains(subquery)) { 10354 analyzeSelectStmt(subquery); 10355 10356 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 10357 if (resultSetModel != null && resultSetModel != queryTable 10358 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 10359 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 10360 impactRelation.setEffectType(EffectType.select); 10361 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 10362 resultSetModel.getRelationRows())); 10363 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 10364 queryTable.getRelationRows())); 10365 } 10366 10367 if (subquery.getSetOperatorType() != ESetOperatorType.none) { 10368 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 10369 .getModel(subquery); 10370 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 10371 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 10372 ResultColumn targetColumn = null; 10373 if (cteColumns != null) { 10374 targetColumn = queryTable.getColumns().get(j); 10375 } else { 10376 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 10377 } 10378 for (Set<TObjectName> starLinkColumns : sourceColumn.getStarLinkColumns().values()) { 10379 for (TObjectName starLinkColumn : starLinkColumns) { 10380 targetColumn.bindStarLinkColumn(starLinkColumn); 10381 } 10382 } 10383 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 10384 selectSetRalation.setEffectType(EffectType.select); 10385 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 10386 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 10387 selectSetRalation.setProcess(process); 10388 } 10389 } else { 10390 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 10391 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 10392 ResultColumn targetColumn = null; 10393 if (cteColumns != null) { 10394 targetColumn = queryTable.getColumns().get(j); 10395 } else { 10396 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 10397 } 10398 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 10399 targetColumn.bindStarLinkColumn(starLinkColumn); 10400 } 10401 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 10402 selectSetRalation.setEffectType(EffectType.select); 10403 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 10404 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 10405 selectSetRalation.setProcess(process); 10406 } 10407 } 10408 } else if (tableElement.getCTE().getUpdateStmt() != null) { 10409 analyzeCustomSqlStmt(tableElement.getCTE().getUpdateStmt()); 10410 } else if (tableElement.getCTE().getInsertStmt() != null) { 10411 analyzeCustomSqlStmt(tableElement.getCTE().getInsertStmt()); 10412 } else if (tableElement.getCTE().getDeleteStmt() != null) { 10413 analyzeCustomSqlStmt(tableElement.getCTE().getDeleteStmt()); 10414 } 10415 } else { 10416 modelFactory.createTable(stmt.tables.getTable(i)); 10417 } 10418 } 10419 10420 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 10421 TResultColumn field = stmt.getResultColumnList().getResultColumn(i); 10422 10423 if (field.getExpr().getExpressionType() == EExpressionType.function_t) { 10424 // Handle SQL Server XML modify() method for data lineage 10425 TFunctionCall funcCall = field.getExpr().getFunctionCall(); 10426 if (funcCall != null && funcCall.getFunctionType() == EFunctionType.xmlmodify_t) { 10427 analyzeXmlModifyFunction(stmt, tableModel, process, funcCall); 10428 } 10429 continue; 10430 } 10431 10432 TExpression expression = field.getExpr().getLeftOperand(); 10433 if (expression == null) { 10434 ErrorInfo errorInfo = new ErrorInfo(); 10435 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 10436 errorInfo.setErrorMessage( 10437 "Can't get result column expression. Expression is " + field.getExpr().toString()); 10438 errorInfo.setStartPosition(new Pair3<Long, Long, String>(field.getExpr().getStartToken().lineNo, 10439 field.getExpr().getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 10440 errorInfo.setEndPosition(new Pair3<Long, Long, String>(field.getExpr().getEndToken().lineNo, 10441 field.getExpr().getEndToken().columnNo + field.getExpr().getEndToken().getAstext().length(), 10442 ModelBindingManager.getGlobalHash())); 10443 errorInfo.fillInfo(this); 10444 errorInfos.add(errorInfo); 10445 continue; 10446 } 10447 if (expression.getExpressionType() == EExpressionType.list_t) { 10448 TExpression setExpression = field.getExpr().getRightOperand(); 10449 if (setExpression != null && setExpression.getSubQuery() != null) { 10450 TSelectSqlStatement query = setExpression.getSubQuery(); 10451 analyzeSelectStmt(query); 10452 10453 SelectResultSet resultSetModel = (SelectResultSet) modelManager 10454 .getModel(query.getResultColumnList()); 10455 10456 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 10457 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 10458 impactRelation.setEffectType(EffectType.update); 10459 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 10460 resultSetModel.getRelationRows())); 10461 impactRelation.setTarget( 10462 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 10463 } 10464 10465 TExpressionList columnList = expression.getExprList(); 10466 for (int j = 0; j < columnList.size(); j++) { 10467 TObjectName column = columnList.getExpression(j).getObjectOperand(); 10468 10469 if (column.getDbObjectType() == EDbObjectType.variable) { 10470 continue; 10471 } 10472 10473 if (column.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql 10474 || option.getVendor() == EDbVendor.dbvazuresql)) { 10475 continue; 10476 } 10477 10478 if (column.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana 10479 || option.getVendor() == EDbVendor.dbvteradata)) { 10480 continue; 10481 } 10482 10483 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 10484 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false); 10485 if (tableColumn != null) { 10486 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10487 relation.setEffectType(EffectType.update); 10488 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10489 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10490 relation.setProcess(process); 10491 } 10492 10493 } 10494 } 10495 } else if (expression.getExpressionType() == EExpressionType.simple_object_name_t) { 10496 TExpression setExpression = field.getExpr().getRightOperand(); 10497 if (setExpression != null && setExpression.getSubQuery() != null) { 10498 TSelectSqlStatement query = setExpression.getSubQuery(); 10499 analyzeSelectStmt(query); 10500 10501 SelectResultSet resultSetModel = (SelectResultSet) modelManager 10502 .getModel(query.getResultColumnList()); 10503 10504 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 10505 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 10506 impactRelation.setEffectType(EffectType.update); 10507 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 10508 resultSetModel.getRelationRows())); 10509 impactRelation.setTarget( 10510 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 10511 } 10512 10513 TObjectName column = expression.getObjectOperand(); 10514 ResultColumn resultColumn = resultSetModel.getColumns().get(0); 10515 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false); 10516 if (tableColumn != null) { 10517 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10518 relation.setEffectType(EffectType.update); 10519 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10520 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10521 relation.setProcess(process); 10522 } 10523 } else if (setExpression != null) { 10524 // ResultSet resultSet = modelFactory.createResultSet(stmt, 10525 // true); 10526 10527 ResultSet resultSet = modelFactory.createResultSet(stmt, false); 10528 10529 createPseudoImpactRelation(stmt, resultSet, EffectType.update); 10530 10531 TObjectName columnObject = expression.getObjectOperand(); 10532 10533 ResultColumn updateColumn = modelFactory.createUpdateResultColumn(resultSet, columnObject); 10534 10535 columnsInExpr visitor = new columnsInExpr(); 10536 field.getExpr().getRightOperand().inOrderTraverse(visitor); 10537 10538 List<TObjectName> objectNames = visitor.getObjectNames(); 10539 List<TParseTreeNode> functions = visitor.getFunctions(); 10540 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 10541 10542 if (functions != null && !functions.isEmpty()) { 10543 analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.update); 10544 } 10545 10546 if (subquerys != null && !subquerys.isEmpty()) { 10547 analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.update); 10548 } 10549 10550 Transform transform = new Transform(); 10551 transform.setType(Transform.EXPRESSION); 10552 transform.setCode(setExpression); 10553 updateColumn.setTransform(transform); 10554 analyzeDataFlowRelation(updateColumn, objectNames, EffectType.update, functions); 10555 10556 List<TParseTreeNode> constants = visitor.getConstants(); 10557 analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.update, functions); 10558 10559 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false); 10560 if(tableColumn!=null) { 10561 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10562 relation.setEffectType(EffectType.update); 10563 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10564 relation.addSource(new ResultColumnRelationshipElement(updateColumn)); 10565 relation.setProcess(process); 10566 } 10567 10568 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 10569 impactRelation.setEffectType(EffectType.update); 10570 impactRelation.addSource( 10571 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 10572 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 10573 tableModel.getRelationRows())); 10574 } 10575 } 10576 } 10577 10578 if (stmt.getJoins() != null && stmt.getJoins().size() > 0) { 10579 for (int i = 0; i < stmt.getJoins().size(); i++) { 10580 TJoin join = stmt.getJoins().getJoin(i); 10581 if (join.getJoinItems() != null) { 10582 for (int j = 0; j < join.getJoinItems().size(); j++) { 10583 TJoinItem joinItem = join.getJoinItems().getJoinItem(j); 10584 TExpression expr = joinItem.getOnCondition(); 10585 analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on, 10586 EffectType.update); 10587 } 10588 } 10589 } 10590 } 10591 10592 if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) { 10593 analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where, 10594 EffectType.update); 10595 } 10596 10597 if (stmt.getOutputClause() != null) { 10598 TOutputClause outputClause = stmt.getOutputClause(); 10599 if (outputClause.getSelectItemList() != null) { 10600 ResultSet resultSet = modelFactory.createResultSet(outputClause, false); 10601 for (int j = 0; j < outputClause.getSelectItemList().size(); j++) { 10602 TResultColumn sourceColumn = outputClause.getSelectItemList().getResultColumn(j); 10603 ResultColumn sourceColumnModel = modelFactory.createResultColumn(resultSet, sourceColumn); 10604 analyzeResultColumn(sourceColumn, EffectType.select); 10605 10606 if (outputClause.getIntoTable() != null) { 10607 Table intoTableModel = modelFactory.createTableByName(outputClause.getIntoTable()); 10608 intoTableModel.addProcess(process); 10609 if (outputClause.getIntoColumnList() != null) { 10610 TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel, 10611 outputClause.getIntoColumnList().getObjectName(j)); 10612 10613 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10614 relation.setEffectType(EffectType.insert); 10615 relation.setTarget(new TableColumnRelationshipElement(intoTableColumn)); 10616 relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel)); 10617 } else if (sourceColumn.getAliasClause() != null 10618 || sourceColumn.getExpr().getObjectOperand() != null) { 10619 TObjectName tableColumnObject = null; 10620 if (sourceColumn.getAliasClause() != null) { 10621 tableColumnObject = sourceColumn.getAliasClause().getAliasName(); 10622 } else { 10623 tableColumnObject = sourceColumn.getExpr().getObjectOperand(); 10624 } 10625 10626 TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel, 10627 tableColumnObject); 10628 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10629 relation.setEffectType(EffectType.insert); 10630 relation.setTarget(new TableColumnRelationshipElement(intoTableColumn)); 10631 relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel)); 10632 } 10633 } 10634 } 10635 } 10636 } 10637 } 10638 10639 /** 10640 * Analyzes SQL Server XML modify() function to extract data lineage from sql:column() references 10641 * in XQuery expressions. 10642 * 10643 * Example SQL: 10644 * SET [Demographics].modify('... sql:column("deleted.LineTotal") ...') 10645 * 10646 * This extracts: 10647 * - Target column: Demographics (from the XML column being modified) 10648 * - Source column: deleted.LineTotal (from sql:column() reference in XQuery) 10649 */ 10650 private void analyzeXmlModifyFunction(TUpdateSqlStatement stmt, Table tableModel, Process process, TFunctionCall funcCall) { 10651 TObjectName funcName = funcCall.getFunctionName(); 10652 if (funcName == null || funcName.getPartToken() == null) { 10653 return; 10654 } 10655 10656 // Get the XML column being modified (e.g., [Demographics] from "[Demographics].modify") 10657 String xmlColumnName = funcName.getPartToken().astext; 10658 10659 // Get the XQuery argument 10660 if (funcCall.getArgs() == null || funcCall.getArgs().size() == 0) { 10661 return; 10662 } 10663 10664 String xqueryString = funcCall.getArgs().getExpression(0).toString(); 10665 10666 // Extract sql:column() references from the XQuery string 10667 List<String> sqlColumnRefs = extractSqlColumnReferences(xqueryString); 10668 if (sqlColumnRefs.isEmpty()) { 10669 return; 10670 } 10671 10672 // Extract XPath target from XQuery (e.g., /IndividualSurvey/TotalPurchaseYTD) 10673 String xpathTarget = extractXPathTarget(xqueryString); 10674 10675 // Build full target column name including XML path 10676 String fullTargetColumnName = xmlColumnName; 10677 if (xpathTarget != null && !xpathTarget.isEmpty()) { 10678 fullTargetColumnName = xmlColumnName + "." + xpathTarget; 10679 } 10680 10681 // Create the target table column for the XML column being modified 10682 TableColumn targetTableColumn = modelFactory.createInsertTableColumn(tableModel, fullTargetColumnName); 10683 10684 // Create source-to-target relationships for each sql:column reference 10685 for (String sqlColRef : sqlColumnRefs) { 10686 // Parse the column reference (e.g., "deleted.LineTotal" -> table="deleted", column="LineTotal") 10687 String[] parts = sqlColRef.split("\\.", 2); 10688 String sourceTableName = parts.length > 1 ? parts[0] : null; 10689 String sourceColumnName = parts.length > 1 ? parts[1] : parts[0]; 10690 10691 // Find the source table in the statement's tables 10692 TTable sourceTable = null; 10693 if (sourceTableName != null && stmt.tables != null) { 10694 for (int j = 0; j < stmt.tables.size(); j++) { 10695 TTable t = stmt.tables.getTable(j); 10696 String tableName = t.getTableName().toString(); 10697 String alias = t.getAliasName(); 10698 if (tableName.equalsIgnoreCase(sourceTableName) || 10699 (alias != null && alias.equalsIgnoreCase(sourceTableName))) { 10700 sourceTable = t; 10701 break; 10702 } 10703 } 10704 } 10705 10706 if (sourceTable != null && targetTableColumn != null) { 10707 // Create a table model for the source if needed 10708 Table sourceTableModel = modelFactory.createTable(sourceTable); 10709 TableColumn sourceColumn = modelFactory.createInsertTableColumn(sourceTableModel, sourceColumnName); 10710 10711 if (sourceColumn != null) { 10712 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10713 relation.setEffectType(EffectType.update); 10714 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 10715 relation.addSource(new TableColumnRelationshipElement(sourceColumn)); 10716 relation.setProcess(process); 10717 relation.setFunction("modify"); 10718 } 10719 } 10720 } 10721 } 10722 10723 /** 10724 * Extracts sql:column() references from an XQuery string. 10725 * Example: 'sql:column("deleted.LineTotal")' -> ["deleted.LineTotal"] 10726 */ 10727 private List<String> extractSqlColumnReferences(String xquery) { 10728 List<String> refs = new ArrayList<>(); 10729 if (xquery == null) { 10730 return refs; 10731 } 10732 10733 int startIdx = 0; 10734 while ((startIdx = xquery.indexOf("sql:column(", startIdx)) >= 0) { 10735 int parenStart = startIdx + "sql:column(".length(); 10736 int parenEnd = xquery.indexOf(")", parenStart); 10737 if (parenEnd < 0) { 10738 break; 10739 } 10740 10741 String arg = xquery.substring(parenStart, parenEnd).trim(); 10742 // Remove quotes (single or double) 10743 if ((arg.startsWith("\"") && arg.endsWith("\"")) || 10744 (arg.startsWith("'") && arg.endsWith("'"))) { 10745 arg = arg.substring(1, arg.length() - 1); 10746 } 10747 10748 if (!arg.isEmpty()) { 10749 refs.add(arg); 10750 } 10751 10752 startIdx = parenEnd + 1; 10753 } 10754 10755 return refs; 10756 } 10757 10758 /** 10759 * Extracts the XPath target from an XQuery modify expression. 10760 * Example: 'replace value of (/IndividualSurvey/TotalPurchaseYTD)[1]' -> "IndividualSurvey.TotalPurchaseYTD" 10761 */ 10762 private String extractXPathTarget(String xquery) { 10763 if (xquery == null) { 10764 return null; 10765 } 10766 10767 // Look for patterns like "(/path/to/element)" or "(/path/to/element)[1]" 10768 int replaceIdx = xquery.indexOf("replace value of"); 10769 if (replaceIdx < 0) { 10770 return null; 10771 } 10772 10773 int parenStart = xquery.indexOf("(/", replaceIdx); 10774 if (parenStart < 0) { 10775 return null; 10776 } 10777 10778 int parenEnd = xquery.indexOf(")", parenStart); 10779 if (parenEnd < 0) { 10780 return null; 10781 } 10782 10783 String xpath = xquery.substring(parenStart + 1, parenEnd); 10784 // Remove any predicates like [1] 10785 int bracketIdx = xpath.indexOf("["); 10786 if (bracketIdx > 0) { 10787 xpath = xpath.substring(0, bracketIdx); 10788 } 10789 10790 // Convert XPath to dot notation (e.g., /IndividualSurvey/TotalPurchaseYTD -> IndividualSurvey.TotalPurchaseYTD) 10791 if (xpath.startsWith("/")) { 10792 xpath = xpath.substring(1); 10793 } 10794 xpath = xpath.replace("/", "."); 10795 10796 return xpath; 10797 } 10798 10799 private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants, 10800 EffectType effectType, List<TParseTreeNode> functions) { 10801 analyzeConstantDataFlowRelation(modelObject, constants, effectType, functions, null); 10802 } 10803 10804 private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants, 10805 EffectType effectType, List<TParseTreeNode> functions, Process process) { 10806 if (constants == null || constants.size() == 0) 10807 return; 10808 10809 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10810 relation.setEffectType(effectType); 10811 relation.setProcess(process); 10812 10813 if (functions != null && !functions.isEmpty()) { 10814 relation.setFunction(getFunctionName(functions.get(0))); 10815 } 10816 10817 if (modelObject instanceof ResultColumn) { 10818 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 10819 10820 } else if (modelObject instanceof TableColumn) { 10821 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 10822 10823 } else { 10824 throw new UnsupportedOperationException(); 10825 } 10826 10827 if (option.isShowConstantTable()) { 10828 Table constantTable = null; 10829 if(modelObject instanceof FunctionResultColumn && ((FunctionResultColumn)modelObject).getFunction() instanceof TFunctionCall) { 10830 TFunctionCall function = (TFunctionCall)((FunctionResultColumn)modelObject).getFunction(); 10831 if(function.getFunctionType() == EFunctionType.struct_t) { 10832 constantTable = modelFactory.createConstantsTable(String.valueOf(function.toString().hashCode())); 10833 } 10834 } 10835 if(constantTable == null) { 10836 constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 10837 } 10838 for (int i = 0; i < constants.size(); i++) { 10839 TParseTreeNode constant = constants.get(i); 10840 if (constant instanceof TConstant) { 10841 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TConstant) constant); 10842 relation.addSource(new ConstantRelationshipElement(constantColumn)); 10843 } else if (constant instanceof TObjectName) { 10844 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TObjectName) constant, 10845 false); 10846 if(constantColumn == null) { 10847 continue; 10848 } 10849 relation.addSource(new ConstantRelationshipElement(constantColumn)); 10850 } 10851 } 10852 } 10853 10854 } 10855 10856 private String getFunctionName(TParseTreeNode parseTreeNode) { 10857 if (parseTreeNode instanceof TFunctionCall) { 10858 return ((TFunctionCall) parseTreeNode).getFunctionName().toString(); 10859 } 10860 if (parseTreeNode instanceof TCaseExpression) { 10861 return "case-when"; 10862 } 10863 return null; 10864 } 10865 10866 private void analyzeCreateViewStmt(TCustomSqlStatement stmt, TSelectSqlStatement subquery, 10867 TViewAliasClause viewAlias, TObjectName viewName) { 10868 10869 if (subquery != null) { 10870 TTableList tables = subquery.getTables(); 10871 if (tables != null) { 10872 for (int i = 0; i < tables.size(); i++) { 10873 TTable table = tables.getTable(i); 10874 TCustomSqlStatement createView = viewDDLMap 10875 .get(DlineageUtil.getTableFullName(table.getTableName().toString())); 10876 if (createView != null) { 10877 analyzeCustomSqlStmt(createView); 10878 } 10879 } 10880 } 10881 analyzeSelectStmt(subquery); 10882 } 10883 10884 10885 if (viewAlias != null && viewAlias.getViewAliasItemList() != null) { 10886 TViewAliasItemList viewItems = viewAlias.getViewAliasItemList(); 10887 Table viewModel = modelFactory.createView(stmt, viewName, true); 10888 viewModel.setFromDDL(true); 10889 viewModel.setDetermined(true); 10890 Process process = modelFactory.createProcess(stmt); 10891 viewModel.addProcess(process); 10892 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 10893 if (resultSetModel != null) { 10894 int resultSetSize = resultSetModel.getColumns().size(); 10895 int viewItemSize = viewItems.size(); 10896 int j = 0; 10897 int viewColumnSize = viewItemSize; 10898 if (resultSetModel.isDetermined() && resultSetSize > viewColumnSize) { 10899 viewColumnSize = resultSetSize; 10900 } 10901 for (int i = 0; i < viewColumnSize && j < resultSetSize; i++) { 10902 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 10903 if (i < viewItemSize) { 10904 TObjectName alias = viewItems.getViewAliasItem(i).getAlias(); 10905 10906 if (!resultSetModel.getColumns().get(j).getName().contains("*")) { 10907 j++; 10908 } else { 10909 if (resultSetSize - j == viewItems.size() - i) { 10910 j++; 10911 } 10912 } 10913 10914 if (alias != null) { 10915 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true); 10916 appendTableColumnToSQLEnv(viewModel, viewColumn); 10917 if (resultColumn != null) { 10918 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10919 relation.setEffectType(EffectType.create_view); 10920 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 10921 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10922 relation.setProcess(process); 10923 } 10924 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 10925 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 10926 (TObjectName) resultColumn.getColumnObject(), i, true); 10927 appendTableColumnToSQLEnv(viewModel, viewColumn); 10928 if (resultColumn != null) { 10929 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10930 relation.setEffectType(EffectType.create_view); 10931 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 10932 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10933 relation.setProcess(process); 10934 } 10935 } else if (resultColumn.getColumnObject() instanceof TResultColumn) { 10936 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 10937 ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), i, true); 10938 appendTableColumnToSQLEnv(viewModel, viewColumn); 10939 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 10940 if (column != null && !column.getStarLinkColumns().isEmpty()) { 10941 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 10942 } 10943 if (resultColumn != null) { 10944 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10945 relation.setEffectType(EffectType.create_view); 10946 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 10947 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10948 relation.setProcess(process); 10949 } 10950 } 10951 } 10952 else if(resultSetModel.isDetermined()){ 10953 TObjectName viewColumnName = new TObjectName(); 10954 viewColumnName.setString(resultColumn.getName()); 10955 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, viewModel.getColumns().size(), true); 10956 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10957 relation.setEffectType(EffectType.create_view); 10958 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 10959 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10960 relation.setProcess(process); 10961 j++; 10962 } 10963 } 10964 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 10965 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 10966 impactRelation.setEffectType(EffectType.create_view); 10967 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 10968 resultSetModel.getRelationRows())); 10969 impactRelation.setTarget( 10970 new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows())); 10971 } 10972 } 10973 10974 if (subquery.getResultColumnList() == null && subquery.getValueClause() != null 10975 && subquery.getValueClause().getValueRows().size() == viewItems.size()) { 10976 for (int i = 0; i < viewItems.size(); i++) { 10977 TObjectName alias = viewItems.getViewAliasItem(i).getAlias(); 10978 10979 if (alias != null) { 10980 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true); 10981 appendTableColumnToSQLEnv(viewModel, viewColumn); 10982 TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr(); 10983 10984 columnsInExpr visitor = new columnsInExpr(); 10985 expression.inOrderTraverse(visitor); 10986 List<TObjectName> objectNames = visitor.getObjectNames(); 10987 List<TParseTreeNode> functions = visitor.getFunctions(); 10988 10989 if (functions != null && !functions.isEmpty()) { 10990 analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select); 10991 10992 } 10993 10994 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 10995 if (subquerys != null && !subquerys.isEmpty()) { 10996 analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select); 10997 } 10998 10999 analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions); 11000 List<TParseTreeNode> constants = visitor.getConstants(); 11001 analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions); 11002 } 11003 } 11004 } 11005 11006 } else { 11007 if (viewName == null) { 11008 ErrorInfo errorInfo = new ErrorInfo(); 11009 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 11010 errorInfo.setErrorMessage("Can't get view name. CreateView is " + stmt.toString()); 11011 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 11012 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 11013 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 11014 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 11015 ModelBindingManager.getGlobalHash())); 11016 errorInfo.fillInfo(this); 11017 errorInfos.add(errorInfo); 11018 return; 11019 } 11020 Table viewModel = modelFactory.createView(stmt, viewName); 11021 Process process = modelFactory.createProcess(stmt); 11022 viewModel.addProcess(process); 11023 if (subquery != null && !subquery.isCombinedQuery()) { 11024 SelectResultSet resultSetModel = (SelectResultSet) modelManager 11025 .getModel(subquery.getResultColumnList()); 11026 11027 boolean determined = false; 11028 if (!containStarColumn(resultSetModel)) { 11029 viewModel.setCreateTable(true); 11030 determined = true; 11031 viewModel.setFromDDL(true); 11032 } 11033 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 11034 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 11035 if (resultColumn.getColumnObject() instanceof TResultColumn) { 11036 TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject()); 11037 11038 TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause(); 11039 if (alias != null && alias.getAliasName() != null) { 11040 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i, 11041 determined); 11042 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11043 relation.setEffectType(EffectType.create_view); 11044 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11045 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11046 relation.setProcess(process); 11047 if (determined) { 11048 appendTableColumnToSQLEnv(viewModel, viewColumn); 11049 } 11050 } else if (columnObject.getFieldAttr() != null) { 11051 TObjectName viewColumnObject = columnObject.getFieldAttr(); 11052 TableColumn viewColumn; 11053 Object model = modelManager.getModel(resultColumn.getColumnObject()); 11054 if ("*".equals(viewColumnObject.getColumnNameOnly())) { 11055 if (model instanceof LinkedHashMap) { 11056 String columnName = getColumnNameOnly(resultColumn.getName()); 11057 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model; 11058 if ("*".equals(columnName)) { 11059 for (String key : resultColumns.keySet()) { 11060 ResultColumn column = resultColumns.get(key); 11061 viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName()); 11062 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11063 relation.setEffectType(EffectType.create_view); 11064 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11065 relation.addSource(new ResultColumnRelationshipElement(column)); 11066 relation.setProcess(process); 11067 } 11068 continue; 11069 } else if (resultColumns.containsKey(columnName)) { 11070 ResultColumn column = resultColumns.get(columnName); 11071 viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName()); 11072 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11073 relation.setEffectType(EffectType.create_view); 11074 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11075 relation.addSource(new ResultColumnRelationshipElement(column)); 11076 relation.setProcess(process); 11077 continue; 11078 } 11079 } 11080 } 11081 11082 if (!SQLUtil.isEmpty(viewColumnObject.getColumnNameOnly()) 11083 && viewColumnObject.getPropertyToken() != null) { 11084 TObjectName object = new TObjectName(); 11085 // object.setString(viewColumnObject.getPropertyToken().astext); 11086 object.setPartToken(viewColumnObject.getPropertyToken()); 11087 object.setStartToken(viewColumnObject.getPropertyToken()); 11088 object.setEndToken(viewColumnObject.getPropertyToken()); 11089 viewColumn = modelFactory.createViewColumn(viewModel, object, i, determined); 11090 } else { 11091 viewColumn = modelFactory.createViewColumn(viewModel, columnObject.getFieldAttr(), 11092 i, determined); 11093 } 11094 11095 if(determined) { 11096 appendTableColumnToSQLEnv(viewModel, viewColumn); 11097 } 11098 11099 if (model instanceof ResultColumn) { 11100 ResultColumn column = (ResultColumn) modelManager 11101 .getModel(resultColumn.getColumnObject()); 11102 if (column != null && !column.getStarLinkColumns().isEmpty()) { 11103 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 11104 } 11105 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11106 relation.setEffectType(EffectType.create_view); 11107 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11108 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11109 if (sqlenv == null) { 11110 if (resultColumn.isShowStar()) { 11111 relation.setShowStarRelation(true); 11112 viewColumn.setShowStar(true); 11113 resultColumn.setShowStar(true); 11114 setSourceShowStar(resultColumn); 11115 } 11116 } 11117 if (viewColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) { 11118 viewModel.setStarStmt("create_view"); 11119 } 11120 relation.setProcess(process); 11121 } 11122 } else if (resultColumn.getAlias() != null && columnObject.getExpr() 11123 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 11124 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11125 columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined); 11126 if(determined) { 11127 appendTableColumnToSQLEnv(viewModel, viewColumn); 11128 } 11129 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11130 relation.setEffectType(EffectType.create_view); 11131 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11132 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11133 relation.setProcess(process); 11134 } else { 11135 TGSqlParser parser = columnObject.getGsqlparser(); 11136 TObjectName viewColumnName = parser 11137 .parseObjectName(generateQuotedName(parser, columnObject.toString())); 11138 if (viewColumnName == null) { 11139 ErrorInfo errorInfo = new ErrorInfo(); 11140 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 11141 errorInfo.setErrorMessage( 11142 "Can't parse view column. Column is " + columnObject.toString()); 11143 errorInfo.setStartPosition(new Pair3<Long, Long, String>( 11144 columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo, 11145 ModelBindingManager.getGlobalHash())); 11146 errorInfo 11147 .setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo, 11148 columnObject.getEndToken().columnNo 11149 + columnObject.getEndToken().getAstext().length(), 11150 ModelBindingManager.getGlobalHash())); 11151 errorInfo.fillInfo(this); 11152 errorInfos.add(errorInfo); 11153 } else { 11154 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i, 11155 determined); 11156 if(determined) { 11157 appendTableColumnToSQLEnv(viewModel, viewColumn); 11158 } 11159 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11160 relation.setEffectType(EffectType.create_view); 11161 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11162 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11163 relation.setProcess(process); 11164 } 11165 } 11166 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 11167 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11168 (TObjectName) resultColumn.getColumnObject(), i, determined); 11169 if(determined) { 11170 appendTableColumnToSQLEnv(viewModel, viewColumn); 11171 } 11172 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11173 relation.setEffectType(EffectType.create_view); 11174 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11175 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11176 relation.setProcess(process); 11177 } 11178 } 11179 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11180 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11181 impactRelation.setEffectType(EffectType.create_view); 11182 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11183 resultSetModel.getRelationRows())); 11184 impactRelation.setTarget( 11185 new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows())); 11186 } 11187 } else if (subquery != null && subquery.isCombinedQuery()) { 11188 SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(subquery); 11189 11190 boolean determined = false; 11191 if (!containStarColumn(resultSetModel)) { 11192 viewModel.setCreateTable(true); 11193 viewModel.setFromDDL(true); 11194 determined = true; 11195 } 11196 11197 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 11198 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 11199 11200 if (resultColumn.getColumnObject() instanceof TResultColumn) { 11201 TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject()); 11202 11203 TAliasClause alias = columnObject.getAliasClause(); 11204 if (alias != null && alias.getAliasName() != null) { 11205 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i, 11206 determined); 11207 if(determined) { 11208 appendTableColumnToSQLEnv(viewModel, viewColumn); 11209 } 11210 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11211 relation.setEffectType(EffectType.create_view); 11212 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11213 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11214 relation.setProcess(process); 11215 } else if (columnObject.getFieldAttr() != null) { 11216 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11217 columnObject.getFieldAttr(), i, determined); 11218 if(determined) { 11219 appendTableColumnToSQLEnv(viewModel, viewColumn); 11220 } 11221 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 11222 if (column != null && !column.getStarLinkColumns().isEmpty()) { 11223 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 11224 } 11225 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11226 relation.setEffectType(EffectType.create_view); 11227 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11228 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11229 relation.setProcess(process); 11230 } else if (resultColumn.getAlias() != null && columnObject.getExpr() 11231 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 11232 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11233 columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined); 11234 if(determined) { 11235 appendTableColumnToSQLEnv(viewModel, viewColumn); 11236 } 11237 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11238 relation.setEffectType(EffectType.create_view); 11239 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11240 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11241 relation.setProcess(process); 11242 } else { 11243 TGSqlParser parser = columnObject.getGsqlparser(); 11244 TObjectName viewColumnName = parser 11245 .parseObjectName(generateQuotedName(parser, columnObject.toString())); 11246 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i, 11247 determined); 11248 if(determined) { 11249 appendTableColumnToSQLEnv(viewModel, viewColumn); 11250 } 11251 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11252 relation.setEffectType(EffectType.create_view); 11253 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11254 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11255 relation.setProcess(process); 11256 } 11257 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 11258 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11259 (TObjectName) resultColumn.getColumnObject(), i, determined); 11260 if(viewColumn!=null) { 11261 if(determined) { 11262 appendTableColumnToSQLEnv(viewModel, viewColumn); 11263 } 11264 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11265 relation.setEffectType(EffectType.create_view); 11266 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11267 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11268 relation.setProcess(process); 11269 } 11270 } 11271 } 11272 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11273 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11274 impactRelation.setEffectType(EffectType.create_view); 11275 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11276 resultSetModel.getRelationRows())); 11277 impactRelation.setTarget( 11278 new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows())); 11279 } 11280 } 11281 } 11282 } 11283 11284 private void setSourceShowStar(Object resultColumn) { 11285 for (Relationship relation : modelManager.getRelations()) { 11286 Collection<RelationshipElement<?>> sources = (Collection<RelationshipElement<?>>)relation.getSources(); 11287 if (relation.getTarget().getElement() == resultColumn && sources != null) { 11288 11289 ((AbstractRelationship) relation).setShowStarRelation(true); 11290 for (RelationshipElement<?> source : sources) { 11291 Object column = source.getElement(); 11292 if (column instanceof TableColumn) { 11293 if (((TableColumn) column).isShowStar()) 11294 continue; 11295 ((TableColumn) column).setShowStar(true); 11296 } 11297 if (column instanceof ResultColumn) { 11298 if (((ResultColumn) column).isShowStar()) 11299 continue; 11300 ((ResultColumn) column).setShowStar(true); 11301 } 11302 setSourceShowStar(column); 11303 } 11304 } 11305 } 11306 } 11307 11308 private String generateQuotedName(TGSqlParser parser, String name) { 11309 return "\"" + name + "\""; 11310 } 11311 11312 private void appendRelations(dataflow dataflow) { 11313 Relationship[] relations = modelManager.getRelations(); 11314 11315 appendRelation(dataflow, relations, DataFlowRelationship.class); 11316 appendRelation(dataflow, relations, IndirectImpactRelationship.class); 11317 appendRecordSetRelation(dataflow, relations); 11318 appendCallRelation(dataflow, relations); 11319 appendRelation(dataflow, relations, ImpactRelationship.class); 11320 appendRelation(dataflow, relations, JoinRelationship.class); 11321 appendRelation(dataflow, relations, ERRelationship.class); 11322 appendRelation(dataflow, relations, CrudRelationship.class); 11323 } 11324 11325 11326 private relationship cloneRelationshipWithSingleSource(relationship orig, sourceColumn src) { 11327 relationship rel = new relationship(); 11328 rel.setType(orig.getType()); 11329 rel.setEffectType(orig.getEffectType()); 11330 rel.setId(orig.getId() + "_" + src.getColumn()); 11331 rel.setSqlHash(orig.getSqlHash()); 11332 rel.setSqlComment(orig.getSqlComment()); 11333 rel.setProcessId(orig.getProcessId()); 11334 rel.setProcessType(orig.getProcessType()); 11335 rel.setFunction(orig.getFunction()); 11336 rel.setProcedureId(orig.getProcedureId()); 11337 11338 targetColumn t = new targetColumn(); 11339 t.setId(orig.getTarget().getId()); 11340 t.setColumn(orig.getTarget().getColumn()); 11341 t.setParent_id(orig.getTarget().getParent_id()); 11342 t.setParent_name(orig.getTarget().getParent_name()); 11343 t.setParent_alias(orig.getTarget().getParent_alias()); 11344 t.setCoordinate(orig.getTarget().getCoordinate()); 11345 rel.setTarget(t); 11346 11347 sourceColumn s = new sourceColumn(); 11348 s.setId(src.getId()); 11349 s.setColumn(src.getColumn()); 11350 s.setParent_id(src.getParent_id()); 11351 s.setParent_name(src.getParent_name()); 11352 s.setCoordinate(src.getCoordinate()); 11353 rel.addSource(s); 11354 return rel; 11355 } 11356 11357 private Set<String> appendStarColumns = new HashSet<String>(); 11358 private void appendRelation(dataflow dataflow, Relationship[] relations, Class<? extends Relationship> clazz) { 11359 for (int i = 0; i < relations.length; i++) { 11360 AbstractRelationship relation = (AbstractRelationship) relations[i]; 11361 if (relation.getClass() == clazz) { 11362 if (relation.getSources() == null || relation.getTarget() == null) { 11363 continue; 11364 } 11365 Object targetElement = relation.getTarget().getElement(); 11366 TObjectName targetColumnName = null; 11367 if(relation.getTarget() instanceof ResultColumnRelationshipElement) { 11368 targetColumnName = ((ResultColumnRelationshipElement) relation.getTarget()).getColumnName(); 11369 } 11370 if (targetElement instanceof ResultColumn) { 11371 ResultColumn targetColumn = (ResultColumn) targetElement; 11372 if (!targetColumn.isPseduo()) 11373 { 11374 if (targetColumnName == null) 11375 { 11376 if ("*".equals(targetColumn.getName())) { 11377 updateResultColumnStarLinks(dataflow, relation, -1); 11378 } 11379 11380 if (targetColumn.hasStarLinkColumn()) { 11381 for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) { 11382 appendStarRelation(dataflow, relation, j); 11383 } 11384 11385 if (!containsStar(relation.getSources())) { 11386 continue; 11387 } 11388 } 11389 } 11390 else { 11391 String columnName = DlineageUtil.getColumnName(targetColumnName); 11392 int index = targetColumn.getStarLinkColumnNames().indexOf(columnName); 11393 if (index != -1) { 11394 int size = targetColumn.getStarLinkColumnNames().size(); 11395 if ("*".equals(targetColumn.getName())) { 11396 if (appendStarColumns.contains(columnName)) { 11397 updateResultColumnStarLinks(dataflow, relation, index); 11398 } 11399 else { 11400 updateResultColumnStarLinks(dataflow, relation, -1); 11401 appendStarColumns.add(columnName); 11402 } 11403 } 11404 appendStarRelation(dataflow, relation, index); 11405 for(int j= size; j < targetColumn.getStarLinkColumnNames().size(); j++) { 11406 appendStarRelation(dataflow, relation, j); 11407 } 11408 if (!containsStar(relation.getSources())) { 11409 continue; 11410 } 11411 } 11412 } 11413 } 11414 } else if (targetElement instanceof TableColumn) { 11415 TableColumn targetColumn = (TableColumn) targetElement; 11416 if (!targetColumn.isPseduo()) { 11417 if ("*".equals(targetColumn.getName())) { 11418 updateTableColumnStarLinks(dataflow, relation); 11419 } 11420 11421 if (targetColumn.hasStarLinkColumn() && !targetColumn.isVariant() 11422 && targetColumn.isExpandStar()) { 11423 for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) { 11424 appendStarRelation(dataflow, relation, j); 11425 } 11426 if (!containsStar(relation.getSources())) { 11427 continue; 11428 } 11429 } 11430 } 11431 } 11432 11433 relationship relationElement = new relationship(); 11434 relationElement.setType(relation.getRelationshipType().name()); 11435 if (relation.getEffectType() != null) { 11436 relationElement.setEffectType(relation.getEffectType().name()); 11437 } 11438 if (relation.getFunction() != null) { 11439 relationElement.setFunction(relation.getFunction()); 11440 } 11441 relationElement.setSqlHash(relation.getSqlHash()); 11442 relationElement.setSqlComment(relation.getSqlComment()); 11443 11444 if (relation.getProcedureId() != null) { 11445 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 11446 } 11447 relationElement.setId(String.valueOf(relation.getId())); 11448 if (relation.getProcess() != null) { 11449 relationElement.setProcessId(String.valueOf(relation.getProcess().getId())); 11450 if (relation.getProcess().getGspObject() != null) { 11451 relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name()); 11452 } 11453 } 11454 11455 if (relation.getPartition() != null) { 11456 relationElement.setPartition(relation.getPartition()); 11457 } 11458 relationElement.setSqlHash(relation.getSqlHash()); 11459 relationElement.setSqlComment(relation.getSqlComment()); 11460 11461 if (relation.getProcedureId() != null) { 11462 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 11463 } 11464 11465 if (relation instanceof JoinRelationship) { 11466 relationElement.setCondition(((JoinRelationship) relation).getJoinCondition()); 11467 relationElement.setJoinType(((JoinRelationship) relation).getJoinType().name()); 11468 relationElement.setClause(((JoinRelationship) relation).getJoinClauseType().name()); 11469 } 11470 11471 if(relation instanceof ImpactRelationship){ 11472 ImpactRelationship impactRelationship = (ImpactRelationship)relation; 11473 if(impactRelationship.getJoinClauseType()!=null){ 11474 relationElement.setClause(impactRelationship.getJoinClauseType().name()); 11475 } 11476 } 11477 11478 String targetName = null; 11479 Object columnObject = null; 11480 List<TObjectName> targetObjectNames = null; 11481 11482 if (targetElement instanceof ResultSetRelationRows) { 11483 ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement; 11484 targetColumn target = new targetColumn(); 11485 target.setId(String.valueOf(targetColumn.getId())); 11486 target.setColumn(targetColumn.getName()); 11487 target.setParent_id(String.valueOf(targetColumn.getHolder().getId())); 11488 target.setParent_name(getResultSetName(targetColumn.getHolder())); 11489 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 11490 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 11491 + convertCoordinate(targetColumn.getEndPosition())); 11492 } 11493 if (relation instanceof RecordSetRelationship) { 11494 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 11495 } 11496 target.setSource("system"); 11497 targetName = targetColumn.getName(); 11498 relationElement.setTarget(target); 11499 } else if (targetElement instanceof TableRelationRows) { 11500 TableRelationRows targetColumn = (TableRelationRows) targetElement; 11501 targetColumn target = new targetColumn(); 11502 target.setId(String.valueOf(targetColumn.getId())); 11503 target.setColumn(targetColumn.getName()); 11504 target.setParent_id(String.valueOf(targetColumn.getHolder().getId())); 11505 target.setParent_name(getTableName(targetColumn.getHolder())); 11506 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 11507 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 11508 + convertCoordinate(targetColumn.getEndPosition())); 11509 } 11510 if (relation instanceof RecordSetRelationship) { 11511 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 11512 } 11513 target.setSource("system"); 11514 targetName = targetColumn.getName(); 11515 relationElement.setTarget(target); 11516 } else if (targetElement instanceof ResultColumn) { 11517 ResultColumn targetColumn = (ResultColumn) targetElement; 11518 targetColumn target = new targetColumn(); 11519 target.setId(String.valueOf(targetColumn.getId())); 11520 target.setColumn(targetColumn.getName()); 11521 target.setStruct(targetColumn.isStruct()); 11522 target.setParent_id(String.valueOf(targetColumn.getResultSet().getId())); 11523 target.setParent_name(getResultSetName(targetColumn.getResultSet())); 11524 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 11525 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 11526 + convertCoordinate(targetColumn.getEndPosition())); 11527 } 11528 if (relation instanceof RecordSetRelationship) { 11529 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 11530 } 11531 targetName = targetColumn.getName(); 11532 if (((ResultColumn) targetColumn).getColumnObject() instanceof TResultColumn) { 11533 columnsInExpr visitor = new columnsInExpr(); 11534 ((TResultColumn) ((ResultColumn) targetColumn).getColumnObject()).getExpr() 11535 .inOrderTraverse(visitor); 11536 targetObjectNames = visitor.getObjectNames(); 11537 } 11538 11539 if (targetElement instanceof FunctionResultColumn) { 11540 columnObject = ((FunctionResultColumn) targetElement).getColumnObject(); 11541 } 11542 if(targetColumn.isPseduo()) { 11543 target.setSource("system"); 11544 } 11545 relationElement.setTarget(target); 11546 } else if (targetElement instanceof TableColumn) { 11547 TableColumn targetColumn = (TableColumn) targetElement; 11548 targetColumn target = new targetColumn(); 11549 target.setId(String.valueOf(targetColumn.getId())); 11550 target.setColumn(targetColumn.getName()); 11551 target.setStruct(targetColumn.isStruct()); 11552 target.setParent_id(String.valueOf(targetColumn.getTable().getId())); 11553 target.setParent_name(getTableName(targetColumn.getTable())); 11554 if (relation.getTarget() instanceof TableColumnRelationshipElement) { 11555 target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias()); 11556 } 11557 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 11558 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 11559 + convertCoordinate(targetColumn.getEndPosition())); 11560 } 11561 if (relation instanceof RecordSetRelationship) { 11562 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 11563 } 11564 if(targetColumn.isPseduo()) { 11565 target.setSource("system"); 11566 } 11567 targetName = targetColumn.getName(); 11568 relationElement.setTarget(target); 11569 } else if (targetElement instanceof Argument) { 11570 Argument targetColumn = (Argument) targetElement; 11571 targetColumn target = new targetColumn(); 11572 target.setId(String.valueOf(targetColumn.getId())); 11573 target.setColumn(targetColumn.getName()); 11574 target.setParent_id(String.valueOf(targetColumn.getProcedure().getId())); 11575 target.setParent_name(targetColumn.getProcedure().getName()); 11576 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 11577 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 11578 + convertCoordinate(targetColumn.getEndPosition())); 11579 } 11580 if (relation instanceof RecordSetRelationship) { 11581 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 11582 } 11583 targetName = targetColumn.getName(); 11584 relationElement.setTarget(target); 11585 } else if (targetElement instanceof Table) { 11586 Table table = (Table) targetElement; 11587 targetColumn target = new targetColumn(); 11588 target.setTarget_id(String.valueOf(table.getId())); 11589 target.setTarget_name(getTableName(table)); 11590 if (table.getStartPosition() != null && table.getEndPosition() != null) { 11591 target.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 11592 + convertCoordinate(table.getEndPosition())); 11593 } 11594 relationElement.setTarget(target); 11595 } else { 11596 continue; 11597 } 11598 11599 Collection<RelationshipElement<?>> sourceElements = relation.getSources(); 11600 if (sourceElements.size() == 0) { 11601 if(clazz == CrudRelationship.class && option.getAnalyzeMode() == AnalyzeMode.crud) { 11602 dataflow.getRelationships().add(relationElement); 11603 } 11604 continue; 11605 } 11606 11607 boolean append = false; 11608 for (RelationshipElement<?> sourceItem: relation.getSources()) { 11609 Object sourceElement = sourceItem.getElement(); 11610 TObjectName sourceColumnName = null; 11611 if (sourceItem instanceof ResultColumnRelationshipElement) { 11612 sourceColumnName = ((ResultColumnRelationshipElement) sourceItem).getColumnName(); 11613 } 11614// if (sourceItem instanceof TableColumnRelationElement 11615// && (((TableColumnRelationElement) sourceItem).getColumnIndex() != null)) { 11616// TableColumnRelationElement tableColumnRelationElement = (TableColumnRelationElement) sourceItem; 11617// sourceElement = tableColumnRelationElement.getElement().getTable().getColumns() 11618// .get(tableColumnRelationElement.getColumnIndex() + 1); 11619// } 11620 if (sourceElement instanceof ResultColumn) { 11621 ResultColumn sourceColumn = (ResultColumn) sourceElement; 11622 if (sourceColumn.hasStarLinkColumn() && !relation.isShowStarRelation() && !sourceColumn.isPseduo()) { 11623 List<String> sourceStarColumnNames = sourceColumn.getStarLinkColumnNames(); 11624 sourceColumn source = new sourceColumn(); 11625 if (targetObjectNames != null && !targetObjectNames.isEmpty()) { 11626 11627 for (int k = 0; k < targetObjectNames.size(); k++) { 11628 String targetObjectName = getColumnName(targetObjectNames.get(k)); 11629 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 11630 boolean find = false; 11631 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 11632 if(column.getName().equalsIgnoreCase(targetObjectName)) { 11633 source = new sourceColumn(); 11634 source.setId(String.valueOf(column.getId())); 11635 source.setColumn(targetObjectName); 11636 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11637 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11638 if (sourceColumn.getStartPosition() != null 11639 && sourceColumn.getEndPosition() != null) { 11640 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 11641 + "," + convertCoordinate(sourceColumn.getEndPosition())); 11642 } 11643 append = true; 11644 relationElement.addSource(source); 11645 find = true; 11646 break; 11647 } 11648 } 11649 if(find) { 11650 continue; 11651 } 11652 } 11653 if (sourceColumn.getStarLinkColumns().containsKey(targetObjectName)) { 11654 source = new sourceColumn(); 11655 source.setId(String.valueOf(sourceColumn.getId()) + "_" 11656 + sourceStarColumnNames.indexOf(targetObjectName)); 11657 source.setColumn(targetObjectName); 11658 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11659 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11660 if (sourceColumn.getStartPosition() != null 11661 && sourceColumn.getEndPosition() != null) { 11662 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 11663 + "," + convertCoordinate(sourceColumn.getEndPosition())); 11664 } 11665 append = true; 11666 relationElement.addSource(source); 11667 } else { 11668 source = new sourceColumn(); 11669 source.setId(String.valueOf(sourceColumn.getId())); 11670 source.setColumn(relationElement.getTarget().getColumn()); 11671 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11672 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11673 if (sourceColumn.getStartPosition() != null 11674 && sourceColumn.getEndPosition() != null) { 11675 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 11676 + "," + convertCoordinate(sourceColumn.getEndPosition())); 11677 } 11678 append = true; 11679 relationElement.addSource(source); 11680 } 11681 } 11682 } else { 11683 if (columnObject instanceof TWhenClauseItemList) { 11684 TCaseExpression expr = (TCaseExpression)((FunctionResultColumn) targetElement).getResultSet().getGspObject(); 11685 List<TExpression> directExpressions = new ArrayList<TExpression>(); 11686 11687// TExpression inputExpr = expr.getInput_expr(); 11688// if (inputExpr != null) { 11689// directExpressions.add(inputExpr); 11690// } 11691 TExpression defaultExpr = expr.getElse_expr(); 11692 if (defaultExpr != null) { 11693 directExpressions.add(defaultExpr); 11694 } 11695 TWhenClauseItemList list = expr.getWhenClauseItemList(); 11696 for (int k = 0; k < list.size(); k++) { 11697 TWhenClauseItem element = list.getWhenClauseItem(k); 11698 directExpressions.add(element.getReturn_expr()); 11699 } 11700 11701 for (int k = 0; k < directExpressions.size(); k++) { 11702 columnsInExpr visitor = new columnsInExpr(); 11703 directExpressions.get(k).inOrderTraverse(visitor); 11704 List<TObjectName> objectNames = visitor.getObjectNames(); 11705 if (objectNames == null) { 11706 continue; 11707 } 11708 for (int x = 0; x < objectNames.size(); x++) { 11709 String objectName = getColumnName(objectNames.get(x)); 11710 if (sourceColumn.getStarLinkColumns().containsKey(objectName)) { 11711 11712 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 11713 boolean find = false; 11714 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 11715 if(column.getName().equalsIgnoreCase(objectName)) { 11716 source = new sourceColumn(); 11717 source.setId(String.valueOf(column.getId())); 11718 source.setColumn(objectName); 11719 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11720 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11721 if (sourceColumn.getStartPosition() != null 11722 && sourceColumn.getEndPosition() != null) { 11723 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 11724 + "," + convertCoordinate(sourceColumn.getEndPosition())); 11725 } 11726 append = true; 11727 relationElement.addSource(source); 11728 find = true; 11729 break; 11730 } 11731 } 11732 if(find) { 11733 continue; 11734 } 11735 } 11736 11737 source.setId(String.valueOf(sourceColumn.getId()) + "_" 11738 + sourceStarColumnNames.indexOf(objectName)); 11739 source.setColumn(objectName); 11740 } else { 11741 source.setId(String.valueOf(sourceColumn.getId())); 11742 source.setColumn(sourceColumn.getName()); 11743 } 11744 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11745 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11746 if (sourceColumn.getStartPosition() != null 11747 && sourceColumn.getEndPosition() != null) { 11748 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 11749 + "," + convertCoordinate(sourceColumn.getEndPosition())); 11750 } 11751 append = true; 11752 relationElement.addSource(source); 11753 } 11754 } 11755 } else { 11756 String objectName = getColumnName(targetName); 11757 boolean find = false; 11758 11759 if (!find && sourceColumn.getStarLinkColumns().containsKey(objectName)) { 11760 source.setId(String.valueOf(sourceColumn.getId()) + "_" 11761 + sourceStarColumnNames.indexOf(objectName)); 11762 source.setColumn(objectName); 11763 find = true; 11764 } 11765 11766 if (!find && sourceColumnName != null) { 11767 objectName = getColumnName(sourceColumnName); 11768 11769 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 11770 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 11771 if(column.getName().equalsIgnoreCase(objectName)) { 11772 source = new sourceColumn(); 11773 source.setId(String.valueOf(column.getId())); 11774 source.setColumn(objectName); 11775 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11776 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11777 if (sourceColumn.getStartPosition() != null 11778 && sourceColumn.getEndPosition() != null) { 11779 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 11780 + "," + convertCoordinate(sourceColumn.getEndPosition())); 11781 } 11782 append = true; 11783 relationElement.addSource(source); 11784 find = true; 11785 break; 11786 } 11787 } 11788 if(find) { 11789 continue; 11790 } 11791 } 11792 11793 if (sourceColumn.getStarLinkColumns().containsKey(objectName)) { 11794 source.setId(String.valueOf(sourceColumn.getId()) + "_" 11795 + sourceStarColumnNames.indexOf(objectName)); 11796 source.setColumn(objectName); 11797 find = true; 11798 } 11799 } 11800 11801 if (!find && sourceItem instanceof ResultColumnRelationshipElement) { 11802 int starIndex = ((ResultColumnRelationshipElement) sourceItem) 11803 .getStarIndex(); 11804 if (starIndex > -1 && sourceColumn.getStarLinkColumnList().size() > starIndex) { 11805 objectName = getColumnName(sourceColumn.getStarLinkColumnList().get(starIndex)); 11806 source.setId(String.valueOf(sourceColumn.getId()) + "_" 11807 + starIndex); 11808 source.setColumn(objectName); 11809 find = true; 11810 } 11811 } 11812 11813 if (!find) { 11814 source.setId(String.valueOf(sourceColumn.getId())); 11815 source.setColumn(sourceColumn.getName()); 11816 } 11817 11818 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11819 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11820 if (sourceColumn.getStartPosition() != null 11821 && sourceColumn.getEndPosition() != null) { 11822 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 11823 + convertCoordinate(sourceColumn.getEndPosition())); 11824 } 11825 append = true; 11826 relationElement.addSource(source); 11827 } 11828 } 11829 11830 } else { 11831 sourceColumn source = new sourceColumn(); 11832 source.setId(String.valueOf(sourceColumn.getId())); 11833 source.setColumn(sourceColumn.getName()); 11834 source.setStruct(sourceColumn.isStruct()); 11835 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 11836 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 11837 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 11838 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 11839 + convertCoordinate(sourceColumn.getEndPosition())); 11840 } 11841 append = true; 11842 if (sourceItem.getTransforms() != null) { 11843 for (Transform transform : sourceItem.getTransforms()) { 11844 source.addTransform(transform); 11845 } 11846 } 11847 if(sourceColumn.isPseduo()) { 11848 source.setSource("system"); 11849 } 11850 relationElement.addSource(source); 11851 } 11852 } else if (sourceElement instanceof TableColumn) { 11853 TableColumn sourceColumn = (TableColumn) sourceElement; 11854 if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn() 11855 && sourceItem instanceof TableColumnRelationshipElement) { 11856 sourceColumn source = new sourceColumn(); 11857 boolean find = false; 11858 if (((TableColumnRelationshipElement) sourceItem).getColumnIndex() != null) { 11859 int columnIndex = ((TableColumnRelationshipElement) sourceItem).getColumnIndex(); 11860 if (sourceColumn.getStarLinkColumns().size() > columnIndex) { 11861 source = new sourceColumn(); 11862 source.setId(String.valueOf(sourceColumn.getId()) + "_" + columnIndex); 11863 String targetObjectName = getColumnName( 11864 sourceColumn.getStarLinkColumnList().get(columnIndex)); 11865 source.setColumn(targetObjectName); 11866 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 11867 source.setParent_name(sourceColumn.getTable().getName()); 11868 if (sourceItem instanceof TableColumnRelationshipElement) { 11869 source.setParent_alias( 11870 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 11871 } 11872 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 11873 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 11874 + convertCoordinate(sourceColumn.getEndPosition())); 11875 } 11876 append = true; 11877 relationElement.addSource(source); 11878 find = true; 11879 } 11880 } 11881 11882 if (!find) { 11883 String objectName = getColumnName(targetName); 11884 11885 table tableElement = null; 11886 if (dataflow.getTables() != null) { 11887 for (table t : dataflow.getTables()) { 11888 if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) { 11889 tableElement = t; 11890 break; 11891 } 11892 } 11893 } 11894 if (tableElement == null && dataflow.getViews() != null) { 11895 for (table t : dataflow.getViews()) { 11896 if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) { 11897 tableElement = t; 11898 break; 11899 } 11900 } 11901 } 11902 if (tableElement == null && dataflow.getVariables() != null) { 11903 for (table t : dataflow.getVariables()) { 11904 if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) { 11905 tableElement = t; 11906 break; 11907 } 11908 } 11909 } 11910 11911 if(tableElement!=null) { 11912 for (column column : tableElement.getColumns()) { 11913 if (column.getName() != null && column.getName().equalsIgnoreCase(objectName)) { 11914 source = new sourceColumn(); 11915 source.setId(String.valueOf(column.getId())); 11916 source.setColumn(objectName); 11917 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 11918 source.setParent_name(sourceColumn.getTable().getName()); 11919 if (sourceItem instanceof TableColumnRelationshipElement) { 11920 source.setParent_alias( 11921 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 11922 } 11923 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 11924 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 11925 + convertCoordinate(sourceColumn.getEndPosition())); 11926 } 11927 if (sourceItem.getTransforms() != null) { 11928 for (Transform transform : sourceItem.getTransforms()) { 11929 source.addTransform(transform); 11930 } 11931 } 11932 if (sourceColumn.getCandidateParents() != null) { 11933 for(Object item: sourceColumn.getCandidateParents()) { 11934 candidateTable candidateParent = new candidateTable(); 11935 if(item instanceof Table) { 11936 candidateParent.setId(String.valueOf(((Table)item).getId())); 11937 candidateParent.setName(getTableName((Table)item)); 11938 source.addCandidateParent(candidateParent); 11939 } 11940 else if(item instanceof ResultSet) { 11941 candidateParent.setId(String.valueOf(((ResultSet)item).getId())); 11942 candidateParent.setName(getResultSetName((ResultSet)item)); 11943 source.addCandidateParent(candidateParent); 11944 } 11945 } 11946 } 11947 append = true; 11948 relationElement.addSource(source); 11949 find = true; 11950 break; 11951 } 11952 } 11953 } 11954 } 11955 11956 if(!find) { 11957 source = new sourceColumn(); 11958 source.setId(String.valueOf(sourceColumn.getId())); 11959 source.setColumn(sourceColumn.getName()); 11960 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 11961 source.setParent_name(sourceColumn.getTable().getName()); 11962 if (sourceItem instanceof TableColumnRelationshipElement) { 11963 source.setParent_alias( 11964 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 11965 } 11966 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 11967 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 11968 + convertCoordinate(sourceColumn.getEndPosition())); 11969 } 11970 if (sourceItem.getTransforms() != null) { 11971 for (Transform transform : sourceItem.getTransforms()) { 11972 source.addTransform(transform); 11973 } 11974 } 11975 if (sourceColumn.getCandidateParents() != null) { 11976 for(Object item: sourceColumn.getCandidateParents()) { 11977 candidateTable candidateParent = new candidateTable(); 11978 if(item instanceof Table) { 11979 candidateParent.setId(String.valueOf(((Table)item).getId())); 11980 candidateParent.setName(getTableName((Table)item)); 11981 source.addCandidateParent(candidateParent); 11982 } 11983 else if(item instanceof ResultSet) { 11984 candidateParent.setId(String.valueOf(((ResultSet)item).getId())); 11985 candidateParent.setName(getResultSetName((ResultSet)item)); 11986 source.addCandidateParent(candidateParent); 11987 } 11988 } 11989 } 11990 append = true; 11991 relationElement.addSource(source); 11992 } 11993 11994 } else { 11995 sourceColumn source = new sourceColumn(); 11996 source.setId(String.valueOf(sourceColumn.getId())); 11997 source.setColumn(sourceColumn.getName()); 11998 source.setStruct(sourceColumn.isStruct()); 11999 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 12000 source.setParent_name(getTableName(sourceColumn.getTable())); 12001 if (sourceItem instanceof TableColumnRelationshipElement) { 12002 source.setParent_alias( 12003 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 12004 } 12005 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12006 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12007 + convertCoordinate(sourceColumn.getEndPosition())); 12008 } 12009 if (sourceItem.getTransforms() != null) { 12010 for (Transform transform : sourceItem.getTransforms()) { 12011 source.addTransform(transform); 12012 } 12013 } 12014 if(sourceColumn.isPseduo()) { 12015 source.setSource("system"); 12016 } 12017 if (sourceColumn.getCandidateParents() != null) { 12018 for(Object item: sourceColumn.getCandidateParents()) { 12019 candidateTable candidateParent = new candidateTable(); 12020 if(item instanceof Table) { 12021 candidateParent.setId(String.valueOf(((Table)item).getId())); 12022 candidateParent.setName(getTableName((Table)item)); 12023 source.addCandidateParent(candidateParent); 12024 } 12025 else if(item instanceof ResultSet) { 12026 candidateParent.setId(String.valueOf(((ResultSet)item).getId())); 12027 candidateParent.setName(getResultSetName((ResultSet)item)); 12028 source.addCandidateParent(candidateParent); 12029 } 12030 } 12031 } 12032 append = true; 12033 relationElement.addSource(source); 12034 } 12035 } else if (sourceElement instanceof Argument) { 12036 Argument sourceColumn = (Argument) sourceElement; 12037 sourceColumn source = new sourceColumn(); 12038 source.setId(String.valueOf(sourceColumn.getId())); 12039 source.setColumn(sourceColumn.getName()); 12040 source.setParent_id(String.valueOf(sourceColumn.getProcedure().getId())); 12041 source.setParent_name(sourceColumn.getProcedure().getName()); 12042 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12043 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12044 + convertCoordinate(sourceColumn.getEndPosition())); 12045 } 12046 append = true; 12047 relationElement.addSource(source); 12048 } else if (sourceElement instanceof TableRelationRows) { 12049 TableRelationRows sourceColumn = (TableRelationRows) sourceElement; 12050 sourceColumn source = new sourceColumn(); 12051 source.setId(String.valueOf(sourceColumn.getId())); 12052 source.setColumn(sourceColumn.getName()); 12053 source.setParent_id(String.valueOf(sourceColumn.getHolder().getId())); 12054 source.setParent_name(getTableName(sourceColumn.getHolder())); 12055 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12056 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12057 + convertCoordinate(sourceColumn.getEndPosition())); 12058 } 12059 source.setSource("system"); 12060 append = true; 12061 relationElement.addSource(source); 12062 } else if (sourceElement instanceof ResultSetRelationRows) { 12063 ResultSetRelationRows sourceColumn = (ResultSetRelationRows) sourceElement; 12064 sourceColumn source = new sourceColumn(); 12065 source.setId(String.valueOf(sourceColumn.getId())); 12066 source.setColumn(sourceColumn.getName()); 12067 source.setParent_id(String.valueOf(sourceColumn.getHolder().getId())); 12068 source.setParent_name(getResultSetName(sourceColumn.getHolder())); 12069 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12070 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12071 + convertCoordinate(sourceColumn.getEndPosition())); 12072 } 12073 source.setSource("system"); 12074 append = true; 12075 relationElement.addSource(source); 12076 } else if (sourceElement instanceof Constant) { 12077 Constant sourceColumn = (Constant) sourceElement; 12078 sourceColumn source = new sourceColumn(); 12079 source.setId(String.valueOf(sourceColumn.getId())); 12080 source.setColumn(sourceColumn.getName()); 12081 source.setColumn_type("constant"); 12082 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12083 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12084 + convertCoordinate(sourceColumn.getEndPosition())); 12085 } 12086 append = true; 12087 relationElement.addSource(source); 12088 } else if (sourceElement instanceof Table) { 12089 Table table = (Table) sourceElement; 12090 sourceColumn source = new sourceColumn(); 12091 source.setSource_id(String.valueOf(table.getId())); 12092 source.setSource_name(getTableName(table)); 12093 if (table.getStartPosition() != null && table.getEndPosition() != null) { 12094 source.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 12095 + convertCoordinate(table.getEndPosition())); 12096 } 12097 append = true; 12098 relationElement.addSource(source); 12099 } 12100 12101 if (relation instanceof ImpactRelationship) { 12102 ESqlClause clause = getSqlClause(sourceItem); 12103 if (clause != null 12104 && (relationElement.getSources() != null && !relationElement.getSources().isEmpty())) { 12105 relationElement.getSources().get(relationElement.getSources().size() - 1) 12106 .setClauseType(clause.name()); 12107 } 12108 } 12109 } 12110 if (append) 12111 dataflow.getRelationships().add(relationElement); 12112 } 12113 } 12114 } 12115 12116 private boolean containsStar(Collection<RelationshipElement<?>> elements) { 12117 if (elements == null || elements.size() == 0) 12118 return false; 12119 12120 for (RelationshipElement<?> element : elements) { 12121 if (element.getElement() instanceof ResultColumn) { 12122 ResultColumn object = (ResultColumn) element.getElement(); 12123 if (object.getName().endsWith("*") && object.isShowStar()) 12124 return true; 12125 } else if (element.getElement() instanceof TableColumn) { 12126 TableColumn object = (TableColumn) element.getElement(); 12127 if (object.getName().endsWith("*") && object.isShowStar()) 12128 return true; 12129 } 12130 } 12131 return false; 12132 } 12133 12134 private Map<String, Set<String>> appendTableStarColumns = new HashMap<String, Set<String>>(); 12135 12136 // Tracks column names that have explicit (non-star) sources per target star column. 12137 // Used across relationships to prevent phantom star expansions. 12138 // Key: target star column ID, Value: set of column names with explicit sources. 12139 private Map<Long, Set<String>> explicitStarTargetColumns = new HashMap<Long, Set<String>>(); 12140 private void updateResultColumnStarLinks(dataflow dataflow, AbstractRelationship relation, int index) { 12141 try { 12142 if (option.getAnalyzeMode() == AnalyzeMode.crud) { 12143 return; 12144 } 12145 12146 ResultColumn targetColumn = (ResultColumn) relation.getTarget().getElement(); 12147 12148 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources(); 12149 if (sourceElements == null || sourceElements.size() == 0) 12150 return; 12151 12152 for (RelationshipElement<?> sourceItem : sourceElements) { 12153 Object sourceElement = sourceItem.getElement(); 12154 if (sourceElement instanceof ResultColumn) { 12155 ResultColumn source = (ResultColumn) sourceElement; 12156 if (source.hasStarLinkColumn()) { 12157 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 12158 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 12159 targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 12160 } 12161 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 12162 } 12163 if (!source.isShowStar()) { 12164 targetColumn.setShowStar(false); 12165 relation.setShowStarRelation(false); 12166 } 12167 } else if (!"*".equals(source.getName())) { 12168 if (source.getColumnObject() instanceof TObjectName) { 12169 if (source instanceof FunctionResultColumn) { 12170 12171 } else { 12172 targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject()); 12173 } 12174 } else if (source.getColumnObject() instanceof TResultColumn) { 12175 TResultColumn sourceColumn = (TResultColumn) source.getColumnObject(); 12176 if (sourceColumn.getAliasClause() != null) { 12177 targetColumn.bindStarLinkColumn(sourceColumn.getAliasClause().getAliasName()); 12178 } else if (sourceColumn.getFieldAttr() != null) { 12179 targetColumn.bindStarLinkColumn(sourceColumn.getFieldAttr()); 12180 } else { 12181 TObjectName column = new TObjectName(); 12182 if (sourceColumn.getExpr().getExpressionType() == EExpressionType.typecast_t) { 12183 column.setString(sourceColumn.getExpr().getLeftOperand().toString()); 12184 } else { 12185 column.setString(sourceColumn.toString()); 12186 } 12187 targetColumn.bindStarLinkColumn(column); 12188 } 12189 } 12190 } 12191 } else if (sourceElement instanceof TableColumn && !targetColumn.isStruct()) { 12192 TableColumn source = (TableColumn) sourceElement; 12193 if (!source.isPseduo() && source.hasStarLinkColumn()) { 12194 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 12195 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 12196 targetColumn.getStarLinkColumns().put(item.getKey(), 12197 new LinkedHashSet<TObjectName>()); 12198 } 12199 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 12200 } 12201 if ((source.getTable().isCreateTable() || source.getTable().hasSQLEnv()) 12202 && !source.isShowStar()) { 12203 targetColumn.setShowStar(false); 12204 relation.setShowStarRelation(false); 12205 } 12206 } else if (!"*".equals(source.getName())) { 12207 targetColumn.bindStarLinkColumn(source.getColumnObject()); 12208 } 12209 } 12210 } 12211 12212 if (targetColumn.hasStarLinkColumn()) { 12213 table resultSetElement = null; 12214 for (table t : dataflow.getResultsets()) { 12215 if (t.getId().equals(String.valueOf(targetColumn.getResultSet().getId()))) { 12216 resultSetElement = t; 12217 break; 12218 } 12219 } 12220 12221 int starColumnCount = 0; 12222 for (column item : resultSetElement.getColumns()) { 12223 if (item.getName() != null && item.getName().endsWith("*")) { 12224 starColumnCount += 1; 12225 } 12226 } 12227 12228 if (resultSetElement != null && starColumnCount <= 1) { 12229 List<String> columns = targetColumn.getStarLinkColumnNames(); 12230 if (index == -1) { 12231 for (int k = 0; k < columns.size(); k++) { 12232 String columnName = columns.get(k); 12233 String id = String.valueOf(targetColumn.getId()) + "_" + k; 12234 if (appendTableStarColumns.containsKey(resultSetElement.getId()) && appendTableStarColumns.get(resultSetElement.getId()).contains(id)) { 12235 continue; 12236 } 12237 column columnElement = new column(); 12238 columnElement.setId(id); 12239 columnElement.setName(columnName); 12240 if (targetColumn.isFunction()) { 12241 columnElement.setIsFunction(String.valueOf(targetColumn.isFunction())); 12242 } 12243 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12244 columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12245 + convertCoordinate(targetColumn.getEndPosition())); 12246 } 12247 12248 if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) { 12249 boolean find = false; 12250 for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) { 12251 ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i); 12252 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()) 12253 .equals(columnName)) { 12254 find = true; 12255 break; 12256 } 12257 } 12258 if (find) { 12259 continue; 12260 } 12261 } 12262 12263 if (!resultSetElement.getColumns().contains(columnElement)) { 12264 resultSetElement.getColumns().add(columnElement); 12265 appendTableStarColumns.putIfAbsent(resultSetElement.getId(), new HashSet<String>()); 12266 appendTableStarColumns.get(resultSetElement.getId()).add(id); 12267 } 12268 } 12269 } else { 12270 int k = index; 12271 String columnName = columns.get(k); 12272 column columnElement = new column(); 12273 columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k); 12274 columnElement.setName(columnName); 12275 if (targetColumn.isFunction()) { 12276 columnElement.setIsFunction(String.valueOf(targetColumn.isFunction())); 12277 } 12278 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12279 columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12280 + convertCoordinate(targetColumn.getEndPosition())); 12281 } 12282 12283 if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) { 12284 boolean find = false; 12285 for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) { 12286 ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i); 12287 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) { 12288 find = true; 12289 break; 12290 } 12291 } 12292 if (find) { 12293 return; 12294 } 12295 } 12296 12297 if (!resultSetElement.getColumns().contains(columnElement)) { 12298 resultSetElement.getColumns().add(columnElement); 12299 } 12300 } 12301 } 12302 } 12303 } catch (Exception e) { 12304 logger.error("updateResultColumnStarLinks occurs unknown exceptions.", e); 12305 } 12306 } 12307 12308 private void updateTableColumnStarLinks(dataflow dataflow, AbstractRelationship relation) { 12309 TableColumn targetColumn = (TableColumn) relation.getTarget().getElement(); 12310 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources(); 12311 if (sourceElements == null || sourceElements.size() == 0) 12312 return; 12313 12314 TableColumn sourceStarColumn = null; 12315 12316 for (RelationshipElement<?> sourceItem: sourceElements) { 12317 Object sourceElement = sourceItem.getElement(); 12318 if (sourceElement instanceof ResultColumn) { 12319 ResultColumn source = (ResultColumn) sourceElement; 12320 if(source.getResultSet() instanceof Function) { 12321 continue; 12322 } 12323 if (source.hasStarLinkColumn()) { 12324 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 12325 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 12326 targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 12327 } 12328 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 12329 } 12330 if (!source.isShowStar()) { 12331 targetColumn.setShowStar(false); 12332 relation.setShowStarRelation(false); 12333 } 12334 } else if (!"*".equals(source.getName())) { 12335 if (source.getColumnObject() instanceof TObjectName) { 12336 targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject()); 12337 } else if (source.getColumnObject() instanceof TResultColumn) { 12338 if (((TResultColumn) source.getColumnObject()).getAliasClause() != null) { 12339 TObjectName field = ((TResultColumn) source.getColumnObject()).getAliasClause() 12340 .getAliasName(); 12341 if (field != null) { 12342 targetColumn.bindStarLinkColumn(field); 12343 } 12344 } else { 12345 TObjectName field = ((TResultColumn) source.getColumnObject()).getFieldAttr(); 12346 if (field != null) { 12347 targetColumn.bindStarLinkColumn(field); 12348 } else { 12349 TObjectName column = new TObjectName(); 12350 if (((TResultColumn) source.getColumnObject()).getExpr() 12351 .getExpressionType() == EExpressionType.typecast_t) { 12352 column.setString(((TResultColumn) source.getColumnObject()).getExpr() 12353 .getLeftOperand().toString()); 12354 } else { 12355 column.setString(((TResultColumn) source.getColumnObject()).toString()); 12356 } 12357 targetColumn.bindStarLinkColumn(column); 12358 } 12359 } 12360 } 12361 } 12362 } else if (sourceElement instanceof TableColumn) { 12363 TableColumn source = (TableColumn) sourceElement; 12364 if (source.hasStarLinkColumn()) { 12365 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 12366 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 12367 targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 12368 } 12369 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 12370 } 12371 for (Map.Entry<String, Set<TObjectName>> item : targetColumn.getStarLinkColumns().entrySet()) { 12372 if (!source.getStarLinkColumns().containsKey(item.getKey())) { 12373 source.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 12374 } 12375 source.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 12376 } 12377 12378 sourceStarColumn = source; 12379 12380 if (source.getTable().isCreateTable() && !source.isShowStar()) { 12381 targetColumn.setShowStar(false); 12382 relation.setShowStarRelation(false); 12383 } 12384 } else if (!"*".equals(source.getName())) { 12385 if (source.isStruct()) { 12386 targetColumn.bindStarLinkColumn(source.getColumnObject()); 12387 } 12388 else { 12389 TObjectName objectName = new TObjectName(); 12390 objectName.setString(DlineageUtil.getColumnNameOnly(source.getName())); 12391 targetColumn.bindStarLinkColumn(objectName); 12392 } 12393 } 12394 } 12395 } 12396 12397 if (targetColumn.hasStarLinkColumn()) { 12398 table tableElement = null; 12399 if (dataflow.getTables() != null) { 12400 for (table t : dataflow.getTables()) { 12401 if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) { 12402 tableElement = t; 12403 break; 12404 } 12405 } 12406 } 12407 if (tableElement == null && dataflow.getViews() != null) { 12408 for (table t : dataflow.getViews()) { 12409 if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) { 12410 tableElement = t; 12411 break; 12412 } 12413 } 12414 } 12415 if (tableElement == null && dataflow.getVariables() != null) { 12416 for (table t : dataflow.getVariables()) { 12417 if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) { 12418 tableElement = t; 12419 break; 12420 } 12421 } 12422 } 12423 12424 if (tableElement != null) { 12425 List<String> columns = new ArrayList<String>(targetColumn.getStarLinkColumns().keySet()); 12426 for (int k = 0; k < columns.size(); k++) { 12427 String columnName = columns.get(k); 12428 if (containStarColumn(targetColumn.getTable().getColumns(), columnName)) { 12429 continue; 12430 } 12431 column columnElement = new column(); 12432 columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k); 12433 columnElement.setName(columnName); 12434 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12435 columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12436 + convertCoordinate(targetColumn.getEndPosition())); 12437 } 12438 if (!tableElement.getColumns().contains(columnElement)) { 12439 tableElement.getColumns().add(columnElement); 12440 } 12441 } 12442 } 12443 } 12444 12445 if (sourceStarColumn != null) { 12446 table tableElement = null; 12447 if (dataflow.getTables() != null) { 12448 for (table t : dataflow.getTables()) { 12449 if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) { 12450 tableElement = t; 12451 break; 12452 } 12453 } 12454 } 12455 if (tableElement == null && dataflow.getViews() != null) { 12456 for (table t : dataflow.getViews()) { 12457 if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) { 12458 tableElement = t; 12459 break; 12460 } 12461 } 12462 } 12463 if (tableElement == null && dataflow.getVariables() != null) { 12464 for (table t : dataflow.getVariables()) { 12465 if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) { 12466 tableElement = t; 12467 break; 12468 } 12469 } 12470 } 12471 12472 if (tableElement != null) { 12473 List<String> columns = new ArrayList<String>(sourceStarColumn.getStarLinkColumns().keySet()); 12474 for (int k = 0; k < columns.size(); k++) { 12475 String columnName = columns.get(k); 12476 if (containStarColumn(sourceStarColumn.getTable().getColumns(), columnName)) { 12477 continue; 12478 } 12479 column columnElement = new column(); 12480 columnElement.setId(sourceStarColumn.getId() + "_" + k); 12481 columnElement.setName(columnName); 12482 if (sourceStarColumn.getStartPosition() != null && sourceStarColumn.getEndPosition() != null) { 12483 columnElement.setCoordinate(convertCoordinate(sourceStarColumn.getStartPosition()) + "," 12484 + convertCoordinate(sourceStarColumn.getEndPosition())); 12485 } 12486 if (!tableElement.getColumns().contains(columnElement)) { 12487 tableElement.getColumns().add(columnElement); 12488 } 12489 } 12490 } 12491 } 12492 } 12493 12494 private ESqlClause getSqlClause(RelationshipElement<?> relationshipElement) { 12495 if (relationshipElement instanceof TableColumnRelationshipElement) { 12496 return ((TableColumnRelationshipElement) relationshipElement).getRelationLocation(); 12497 } else if (relationshipElement instanceof ResultColumnRelationshipElement) { 12498 return ((ResultColumnRelationshipElement) relationshipElement).getRelationLocation(); 12499 } 12500 return null; 12501 } 12502 12503 private void appendStarRelation(dataflow dataflow, AbstractRelationship relation, int index) { 12504 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 12505 return; 12506 } 12507 12508 Object targetElement = relation.getTarget().getElement(); 12509 12510 relationship relationElement = new relationship(); 12511 relationElement.setType(relation.getRelationshipType().name()); 12512 if (relation.getEffectType() != null) { 12513 relationElement.setEffectType(relation.getEffectType().name()); 12514 } 12515 relationElement.setSqlHash(relation.getSqlHash()); 12516 relationElement.setSqlComment(relation.getSqlComment()); 12517 12518 if (relation.getProcedureId() != null) { 12519 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 12520 } 12521 relationElement.setId(String.valueOf(relation.getId()) + "_" + index); 12522 if (relation.getProcess() != null) { 12523 relationElement.setProcessId(String.valueOf(relation.getProcess().getId())); 12524 if (relation.getProcess().getGspObject() != null) { 12525 relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name()); 12526 } 12527 } 12528 if (relation instanceof DataFlowRelationship) { 12529 relationElement.setSqlHash(((DataFlowRelationship) relation).getSqlHash()); 12530 relationElement.setSqlComment(((DataFlowRelationship) relation).getSqlComment()); 12531 12532 if (relation.getProcedureId() != null) { 12533 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 12534 } 12535 } 12536 String targetName = ""; 12537 12538 if (targetElement instanceof ResultColumn) { 12539 ResultColumn targetColumn = (ResultColumn) targetElement; 12540 12541 targetName = targetColumn.getStarLinkColumnNames().get(index); 12542 12543 12544 targetColumn target = new targetColumn(); 12545 target.setId(String.valueOf(targetColumn.getId()) + "_" + index); 12546 if(targetColumn.getResultSet()!=null && targetColumn.getResultSet().getColumns()!=null) { 12547 for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) { 12548 ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i); 12549 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(targetName)) { 12550 target.setId(String.valueOf(columnModel.getId())); 12551 break; 12552 } 12553 } 12554 } 12555 target.setColumn(targetName); 12556 target.setStruct(targetColumn.isStruct()); 12557 target.setParent_id(String.valueOf(targetColumn.getResultSet().getId())); 12558 target.setParent_name(getResultSetName(targetColumn.getResultSet())); 12559 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12560 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12561 + convertCoordinate(targetColumn.getEndPosition())); 12562 } 12563 relationElement.setTarget(target); 12564 } else if (targetElement instanceof TableColumn) { 12565 TableColumn targetColumn = (TableColumn) targetElement; 12566 12567 targetName = targetColumn.getStarLinkColumnNames().get(index); 12568 12569 TableColumn tableColumn = searchTableColumn(targetColumn.getTable().getColumns(), targetName); 12570 12571 targetColumn target = new targetColumn(); 12572 if (tableColumn == null) { 12573 target.setId(targetColumn.getId() + "_" + index); 12574 } else { 12575 target.setId(String.valueOf(tableColumn.getId())); 12576 } 12577 target.setStruct(targetColumn.isStruct()); 12578 target.setColumn(targetName); 12579 target.setParent_id(String.valueOf(targetColumn.getTable().getId())); 12580 target.setParent_name(targetColumn.getTable().getName()); 12581 if (relation.getTarget() instanceof TableColumnRelationshipElement) { 12582 target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias()); 12583 } 12584 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12585 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12586 + convertCoordinate(targetColumn.getEndPosition())); 12587 } 12588 relationElement.setTarget(target); 12589 } else { 12590 return; 12591 } 12592 12593 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources(); 12594 if (sourceElements.size() == 0) { 12595 return; 12596 } 12597 12598 String targetIdentifierName = DlineageUtil.getIdentifierNormalColumnName(targetName); 12599 if (targetIdentifierName == null) { 12600 return; 12601 } 12602 12603 // Track explicit (non-star) source columns per target star column to prevent 12604 // phantom star expansions. Skip for UNION targets where branches contribute independently. 12605 long targetColumnId = -1; 12606 boolean isUnionTarget = false; 12607 if (targetElement instanceof ResultColumn) { 12608 ResultColumn tc = (ResultColumn) targetElement; 12609 targetColumnId = tc.getId(); 12610 isUnionTarget = (tc.getResultSet() instanceof SelectSetResultSet); 12611 } else if (targetElement instanceof TableColumn) { 12612 targetColumnId = ((TableColumn) targetElement).getId(); 12613 } 12614 12615 if (!isUnionTarget && targetColumnId != -1) { 12616 // Check if any source in this relationship is a non-star source matching the target 12617 // column name, AND whose parent does NOT also contribute a star source. 12618 // This distinguishes: 12619 // - "b.col_a" (definitive: b only provides explicit cols, not *) => suppress star expansion 12620 // - "aTab.id" (not definitive: aTab also provides *) => don't suppress 12621 boolean hasDefinitiveExplicitSource = hasDefinitiveNonStarSource(sourceElements, targetIdentifierName); 12622 if (hasDefinitiveExplicitSource) { 12623 if (!explicitStarTargetColumns.containsKey(targetColumnId)) { 12624 explicitStarTargetColumns.put(targetColumnId, new HashSet<String>()); 12625 } 12626 explicitStarTargetColumns.get(targetColumnId).add(targetIdentifierName); 12627 } 12628 } 12629 12630 // Column names that have explicit (non-star) sources for this target, across all relationships 12631 Set<String> targetExplicitNames = isUnionTarget ? null : explicitStarTargetColumns.get(targetColumnId); 12632 12633 for (RelationshipElement<?> sourceItem: sourceElements) { 12634 Object sourceElement = sourceItem.getElement(); 12635 if (sourceElement instanceof ResultColumn) { 12636 ResultColumn sourceColumn = (ResultColumn) sourceElement; 12637 if (sourceColumn.hasStarLinkColumn()) { 12638 List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames(); 12639 int linkColumnNameSize = linkColumnNames.size(); 12640 for (int k = 0; k < linkColumnNameSize; k++) { 12641 String sourceName = linkColumnNames.get(k); 12642 if (relation.getRelationshipType() == RelationshipType.fdd) { 12643 if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName)) 12644 continue; 12645 } 12646 // Skip star-expanded source when an explicit (non-star) source provides 12647 // the same column, either in this relationship or a prior one. 12648 if (targetExplicitNames != null && targetExplicitNames.contains(sourceName)) { 12649 continue; 12650 } 12651 sourceColumn source = new sourceColumn(); 12652 12653 boolean find = false; 12654 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 12655 for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) { 12656 ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i); 12657 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(sourceName)) { 12658 source.setId(String.valueOf(columnModel.getId())); 12659 find = true; 12660 break; 12661 } 12662 } 12663 } 12664 if(!find) { 12665 source.setId(String.valueOf(sourceColumn.getId()) + "_" + k); 12666 } 12667 source.setColumn(sourceName); 12668 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12669 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12670 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12671 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12672 + convertCoordinate(sourceColumn.getEndPosition())); 12673 } 12674 if (sourceItem.getTransforms() != null) { 12675 for (Transform transform : sourceItem.getTransforms()) { 12676 source.addTransform(transform); 12677 } 12678 } 12679 relationElement.addSource(source); 12680 } 12681 if(relationElement.getSources().isEmpty() 12682 && !(targetExplicitNames != null && targetExplicitNames.contains(targetIdentifierName)) 12683 && sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 12684 for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) { 12685 ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i); 12686 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equalsIgnoreCase(targetIdentifierName)) { 12687 sourceColumn source = new sourceColumn(); 12688 source.setId(String.valueOf(columnModel.getId())); 12689 source.setColumn(columnModel.getName()); 12690 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12691 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12692 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12693 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12694 + convertCoordinate(sourceColumn.getEndPosition())); 12695 } 12696 if (sourceItem.getTransforms() != null) { 12697 for (Transform transform : sourceItem.getTransforms()) { 12698 source.addTransform(transform); 12699 } 12700 } 12701 relationElement.addSource(source); 12702 break; 12703 } 12704 } 12705 } 12706 if (relationElement.getSources().isEmpty() 12707 && !(targetExplicitNames != null && targetExplicitNames.contains(targetIdentifierName))) { 12708 TObjectName sourceStarLinkColumn = new TObjectName(); 12709 sourceStarLinkColumn.setString(targetName); 12710 boolean newBinding = sourceColumn.bindStarLinkColumn(sourceStarLinkColumn); 12711 sourceColumn source = new sourceColumn(); 12712 String sourceName = DlineageUtil.getColumnName(sourceStarLinkColumn); 12713 if (!newBinding) { 12714 source.setId(String.valueOf(sourceColumn.getId()) + "_" 12715 + sourceColumn.indexOfStarLinkColumn(sourceStarLinkColumn)); 12716 } else { 12717 source.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize); 12718 } 12719 source.setColumn(sourceName); 12720 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12721 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12722 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12723 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12724 + convertCoordinate(sourceColumn.getEndPosition())); 12725 } 12726 if (sourceItem.getTransforms() != null) { 12727 for (Transform transform : sourceItem.getTransforms()) { 12728 source.addTransform(transform); 12729 } 12730 } 12731 relationElement.addSource(source); 12732 12733 if (newBinding) { 12734 table resultSetElement = null; 12735 for (table t : dataflow.getResultsets()) { 12736 if (t.getId().equals(String.valueOf(sourceColumn.getResultSet().getId()))) { 12737 resultSetElement = t; 12738 break; 12739 } 12740 } 12741 if (resultSetElement != null) { 12742 column columnElement = new column(); 12743 columnElement.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize); 12744 columnElement.setName(sourceName); 12745 if (sourceColumn.isFunction()) { 12746 columnElement.setIsFunction(String.valueOf(sourceColumn.isFunction())); 12747 } 12748 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12749 columnElement.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12750 + convertCoordinate(sourceColumn.getEndPosition())); 12751 } 12752 resultSetElement.getColumns().add(columnElement); 12753 } 12754 } 12755 } 12756 } else { 12757 sourceColumn source = new sourceColumn(); 12758 source.setId(String.valueOf(sourceColumn.getId())); 12759 source.setColumn(sourceColumn.getName()); 12760 source.setStruct(sourceColumn.isStruct()); 12761 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12762 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12763 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12764 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12765 + convertCoordinate(sourceColumn.getEndPosition())); 12766 } 12767 if (relation.getRelationshipType() == RelationshipType.fdd) { 12768 if (!targetIdentifierName 12769 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))) { 12770 if (!"*".equals(sourceColumn.getName())) { 12771 continue; 12772 } 12773 else { 12774 boolean flag = false; 12775 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 12776 if(targetIdentifierName 12777 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 12778 flag = true; 12779 break; 12780 } 12781 } 12782 if(flag) { 12783 continue; 12784 } 12785 } 12786 } 12787 } 12788 if (sourceItem.getTransforms() != null) { 12789 for (Transform transform : sourceItem.getTransforms()) { 12790 source.addTransform(transform); 12791 } 12792 } 12793 relationElement.addSource(source); 12794 } 12795 } else if (sourceElement instanceof TableColumn) { 12796 TableColumn sourceColumn = (TableColumn) sourceElement; 12797 if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()) { 12798 List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames(); 12799 int linkColumnNameSize = linkColumnNames.size(); 12800 for (int k = 0; k < linkColumnNameSize; k++) { 12801 String sourceName = linkColumnNames.get(k); 12802 if (relation.getRelationshipType() == RelationshipType.fdd) { 12803 if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName)) 12804 continue; 12805 } 12806 12807 TableColumn tableColumn = searchTableColumn(sourceColumn.getTable().getColumns(), sourceName); 12808 12809 sourceColumn source = new sourceColumn(); 12810 if (tableColumn == null) { 12811 source.setId(sourceColumn.getId() + "_" + k); 12812 } else { 12813 source.setId(String.valueOf(tableColumn.getId())); 12814 } 12815 source.setColumn(sourceName); 12816 source.setStruct(sourceColumn.isStruct()); 12817 if (containStarColumn(sourceElements, sourceName)) { 12818 continue; 12819 } 12820 // Cross-relationship check: skip if explicit source was found in prior relationship 12821 if (targetExplicitNames != null && targetExplicitNames.contains(sourceName)) { 12822 continue; 12823 } 12824 if (sourceColumn.getTable().getColumns().size() > 1) { 12825 for (int y = 0; y < sourceColumn.getTable().getColumns().size(); y++) { 12826 if (sourceColumn.getTable().getColumns().get(y).getName() 12827 .equalsIgnoreCase(sourceName)) { 12828 source.setId(String.valueOf(sourceColumn.getTable().getColumns().get(y).getId())); 12829 break; 12830 } 12831 } 12832 } 12833 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 12834 source.setParent_name(getTableName(sourceColumn.getTable())); 12835 if (sourceItem instanceof TableColumnRelationshipElement) { 12836 source.setParent_alias( 12837 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 12838 } 12839 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12840 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12841 + convertCoordinate(sourceColumn.getEndPosition())); 12842 } 12843 if (sourceItem.getTransforms() != null) { 12844 for (Transform transform : sourceItem.getTransforms()) { 12845 source.addTransform(transform); 12846 } 12847 } 12848 relationElement.addSource(source); 12849 } 12850 } else { 12851 sourceColumn source = new sourceColumn(); 12852 source.setId(String.valueOf(sourceColumn.getId())); 12853 source.setColumn(sourceColumn.getName()); 12854 source.setStruct(sourceColumn.isStruct()); 12855 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 12856 source.setParent_name(getTableName(sourceColumn.getTable())); 12857 if (sourceItem instanceof TableColumnRelationshipElement) { 12858 source.setParent_alias(((TableColumnRelationshipElement) sourceItem).getTableAlias()); 12859 } 12860 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12861 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12862 + convertCoordinate(sourceColumn.getEndPosition())); 12863 } 12864 if (relation.getRelationshipType() == RelationshipType.fdd) { 12865 if (!targetIdentifierName 12866 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName())) 12867 && !"*".equals(sourceColumn.getName())) 12868 continue; 12869 } 12870 if (sourceItem.getTransforms() != null) { 12871 for (Transform transform : sourceItem.getTransforms()) { 12872 source.addTransform(transform); 12873 } 12874 } 12875 relationElement.addSource(source); 12876 } 12877 } 12878 } 12879 12880 if (relationElement.getTarget() != null && relationElement.getSources() != null 12881 && !relationElement.getSources().isEmpty()) { 12882 dataflow.getRelationships().add(relationElement); 12883 } 12884 } 12885 12886 private String getColumnName(TObjectName column) { 12887 if (column == null) { 12888 return null; 12889 } 12890 String name = column.getColumnNameOnly(); 12891 if (name == null || "".equals(name.trim())) { 12892 return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim()); 12893 } else 12894 return DlineageUtil.getIdentifierNormalColumnName(name.trim()); 12895 } 12896 12897 /** 12898 * For BigQuery/Redshift struct field access, returns the full struct path 12899 * (e.g., "customer.name" from ColumnSource with exposedName="customer", fieldPath=["name"]). 12900 * Checks StructFieldHint first (for 3+ part no-alias), then ColumnSource (for 2-part/alias). 12901 * Returns null if this is not a struct field access. 12902 */ 12903 private String getStructFieldFullName(TObjectName column) { 12904 if (column == null) return null; 12905 if (getOption().getVendor() != EDbVendor.dbvbigquery 12906 && getOption().getVendor() != EDbVendor.dbvredshift) return null; 12907 // Priority 1: StructFieldHint (side-channel, for 3+ part no-alias deep struct access) 12908 gudusoft.gsqlparser.resolver2.model.StructFieldHint hint = column.getStructFieldHint(); 12909 if (hint != null && hint.getFieldPath() != null && !hint.getFieldPath().isEmpty()) { 12910 return hint.toFullReference(); 12911 } 12912 // Priority 2: ColumnSource (main resolution, for 2-part and alias cases) 12913 gudusoft.gsqlparser.resolver2.model.ColumnSource source = column.getColumnSource(); 12914 if (source != null && source.isStructFieldAccess() && source.hasFieldPath()) { 12915 return source.getFieldPath().toFullReference(source.getExposedName()); 12916 } 12917 return null; 12918 } 12919 12920 /** 12921 * Get the base column name for a struct field access column. 12922 * Checks StructFieldHint first (3+ part no-alias), then ColumnSource (2-part/alias). 12923 * Returns null if not a struct field access. 12924 */ 12925 private String getStructFieldBaseName(TObjectName column) { 12926 if (column == null) return null; 12927 gudusoft.gsqlparser.resolver2.model.StructFieldHint hint = column.getStructFieldHint(); 12928 if (hint != null && hint.getBaseColumn() != null) { 12929 return hint.getBaseColumn(); 12930 } 12931 gudusoft.gsqlparser.resolver2.model.ColumnSource source = column.getColumnSource(); 12932 if (source != null && source.isStructFieldAccess()) { 12933 return source.getExposedName(); 12934 } 12935 return null; 12936 } 12937 12938 private String getColumnName(String column) { 12939 if (column == null) { 12940 return null; 12941 } 12942 String name = column.substring(column.lastIndexOf(".") + 1); 12943 if (name == null || "".equals(name.trim())) { 12944 return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim()); 12945 } else 12946 return DlineageUtil.getIdentifierNormalColumnName(name.trim()); 12947 } 12948 12949 private String getColumnNameOnly(String column) { 12950 if (column == null) { 12951 return null; 12952 } 12953 return DlineageUtil.getColumnNameOnly(column); 12954 } 12955 12956 private void appendRecordSetRelation(dataflow dataflow, Relationship[] relations) { 12957 for (int i = 0; i < relations.length; i++) { 12958 AbstractRelationship relation = (AbstractRelationship) relations[i]; 12959 relationship relationElement = new relationship(); 12960 relationElement.setType(relation.getRelationshipType().name()); 12961 if (relation.getFunction() != null) { 12962 relationElement.setFunction(relation.getFunction()); 12963 } 12964 if (relation.getEffectType() != null) { 12965 relationElement.setEffectType(relation.getEffectType().name()); 12966 } 12967 relationElement.setSqlHash(relation.getSqlHash()); 12968 relationElement.setSqlComment(relation.getSqlComment()); 12969 12970 if (relation.getProcedureId() != null) { 12971 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 12972 } 12973 relationElement.setId(String.valueOf(relation.getId())); 12974 12975 if (relation instanceof RecordSetRelationship) { 12976 RecordSetRelationship recordCountRelation = (RecordSetRelationship) relation; 12977 12978 Object targetElement = recordCountRelation.getTarget().getElement(); 12979 if (targetElement instanceof ResultColumn) { 12980 ResultColumn targetColumn = (ResultColumn) targetElement; 12981 targetColumn target = new targetColumn(); 12982 target.setId(String.valueOf(targetColumn.getId())); 12983 target.setColumn(targetColumn.getName()); 12984 target.setStruct(targetColumn.isStruct()); 12985 target.setFunction(recordCountRelation.getAggregateFunction()); 12986 target.setParent_id(String.valueOf(targetColumn.getResultSet().getId())); 12987 target.setParent_name(getResultSetName(targetColumn.getResultSet())); 12988 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12989 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12990 + convertCoordinate(targetColumn.getEndPosition())); 12991 } 12992 relationElement.setTarget(target); 12993 } else if (targetElement instanceof TableColumn) { 12994 TableColumn targetColumn = (TableColumn) targetElement; 12995 targetColumn target = new targetColumn(); 12996 target.setId(String.valueOf(targetColumn.getId())); 12997 target.setColumn(targetColumn.getName()); 12998 target.setStruct(targetColumn.isStruct()); 12999 target.setFunction(recordCountRelation.getAggregateFunction()); 13000 target.setParent_id(String.valueOf(targetColumn.getTable().getId())); 13001 target.setParent_name(getTableName(targetColumn.getTable())); 13002 if (recordCountRelation.getTarget() instanceof TableColumnRelationshipElement) { 13003 target.setParent_alias( 13004 ((TableColumnRelationshipElement) recordCountRelation.getTarget()).getTableAlias()); 13005 } 13006 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13007 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13008 + convertCoordinate(targetColumn.getEndPosition())); 13009 } 13010 relationElement.setTarget(target); 13011 } else if (targetElement instanceof ResultSetRelationRows) { 13012 ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement; 13013 targetColumn target = new targetColumn(); 13014 target.setId(String.valueOf(targetColumn.getId())); 13015 target.setColumn(targetColumn.getName()); 13016 target.setParent_id(String.valueOf(targetColumn.getHolder().getId())); 13017 target.setParent_name(getResultSetName(targetColumn.getHolder())); 13018 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13019 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13020 + convertCoordinate(targetColumn.getEndPosition())); 13021 } 13022 target.setSource("system"); 13023 relationElement.setTarget(target); 13024 } else { 13025 continue; 13026 } 13027 13028 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)recordCountRelation.getSources(); 13029 if (sourceElements.size() == 0) { 13030 continue; 13031 } 13032 13033 boolean append = false; 13034 for (RelationshipElement<?> sourceItem: sourceElements) { 13035 Object sourceElement = sourceItem.getElement(); 13036 if (sourceElement instanceof Table) { 13037 Table table = (Table) sourceElement; 13038 sourceColumn source = new sourceColumn(); 13039 source.setSource_id(String.valueOf(table.getId())); 13040 source.setSource_name(getTableName(table)); 13041 if (table.getStartPosition() != null && table.getEndPosition() != null) { 13042 source.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 13043 + convertCoordinate(table.getEndPosition())); 13044 } 13045 append = true; 13046 relationElement.addSource(source); 13047 } else if (sourceElement instanceof QueryTable) { 13048 QueryTable table = (QueryTable) sourceElement; 13049 sourceColumn source = new sourceColumn(); 13050 source.setSource_id(String.valueOf(table.getId())); 13051 source.setSource_name(getResultSetName(table)); 13052 if (table.getStartPosition() != null && table.getEndPosition() != null) { 13053 source.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 13054 + convertCoordinate(table.getEndPosition())); 13055 } 13056 append = true; 13057 relationElement.addSource(source); 13058 } else if (sourceElement instanceof TableRelationRows) { 13059 TableRelationRows relationRows = (TableRelationRows) sourceElement; 13060 sourceColumn source = new sourceColumn(); 13061 source.setId(String.valueOf(relationRows.getId())); 13062 source.setColumn(relationRows.getName()); 13063 source.setParent_id(String.valueOf(relationRows.getHolder().getId())); 13064 source.setParent_name(getTableName(relationRows.getHolder())); 13065 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 13066 source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 13067 + convertCoordinate(relationRows.getEndPosition())); 13068 } 13069 source.setSource("system"); 13070 append = true; 13071 relationElement.addSource(source); 13072 } else if (sourceElement instanceof ResultSetRelationRows) { 13073 ResultSetRelationRows relationRows = (ResultSetRelationRows) sourceElement; 13074 sourceColumn source = new sourceColumn(); 13075 source.setId(String.valueOf(relationRows.getId())); 13076 source.setColumn(relationRows.getName()); 13077 source.setParent_id(String.valueOf(relationRows.getHolder().getId())); 13078 source.setParent_name(getResultSetName(relationRows.getHolder())); 13079 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 13080 source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 13081 + convertCoordinate(relationRows.getEndPosition())); 13082 } 13083 source.setSource("system"); 13084 append = true; 13085 relationElement.addSource(source); 13086 } else if (sourceElement instanceof TableColumn) { 13087 TableColumn sourceColumn = (TableColumn) sourceElement; 13088 sourceColumn source = new sourceColumn(); 13089 source.setId(String.valueOf(sourceColumn.getId())); 13090 source.setColumn(sourceColumn.getName()); 13091 source.setStruct(sourceColumn.isStruct()); 13092 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 13093 source.setParent_name(getTableName(sourceColumn.getTable())); 13094 if (sourceItem instanceof TableColumnRelationshipElement) { 13095 source.setParent_alias( 13096 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 13097 } 13098 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13099 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13100 + convertCoordinate(sourceColumn.getEndPosition())); 13101 } 13102 append = true; 13103 relationElement.addSource(source); 13104 } 13105 if (sourceElement instanceof ResultColumn) { 13106 ResultColumn sourceColumn = (ResultColumn) sourceElement; 13107 sourceColumn source = new sourceColumn(); 13108 source.setId(String.valueOf(sourceColumn.getId())); 13109 source.setColumn(sourceColumn.getName()); 13110 source.setStruct(sourceColumn.isStruct()); 13111 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 13112 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 13113 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13114 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13115 + convertCoordinate(sourceColumn.getEndPosition())); 13116 } 13117 append = true; 13118 relationElement.addSource(source); 13119 } 13120 } 13121 13122 if (append) 13123 dataflow.getRelationships().add(relationElement); 13124 } 13125 } 13126 } 13127 13128 private void appendCallRelation(dataflow dataflow, Relationship[] relations) { 13129 for (int i = 0; i < relations.length; i++) { 13130 AbstractRelationship relation = (AbstractRelationship) relations[i]; 13131 relationship relationElement = new relationship(); 13132 relationElement.setType(relation.getRelationshipType().name()); 13133 if (relation.getFunction() != null) { 13134 relationElement.setFunction(relation.getFunction()); 13135 } 13136 if (relation.getEffectType() != null) { 13137 relationElement.setEffectType(relation.getEffectType().name()); 13138 } 13139 relationElement.setSqlHash(relation.getSqlHash()); 13140 relationElement.setSqlComment(relation.getSqlComment()); 13141 13142 if (relation.getProcedureId() != null) { 13143 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 13144 } 13145 relationElement.setId(String.valueOf(relation.getId())); 13146 13147 if (relation instanceof CallRelationship) { 13148 CallRelationship callRelation = (CallRelationship) relation; 13149 13150 if (callRelation.getCallObject() != null) { 13151 relationElement.setCallStmt(callRelation.getCallObject().toString()); 13152 if (callRelation.getStartPosition() != null && callRelation.getEndPosition() != null) { 13153 relationElement.setCallCoordinate(convertCoordinate(callRelation.getStartPosition()) + "," 13154 + convertCoordinate(callRelation.getEndPosition())); 13155 } 13156 } 13157 13158 if (Boolean.TRUE.equals(callRelation.getBuiltIn())) { 13159 relationElement.setBuiltIn(true); 13160 } 13161 Object targetElement = callRelation.getTarget().getElement(); 13162 if (targetElement instanceof Procedure) { 13163 Procedure procedure = (Procedure) targetElement; 13164 targetColumn target = new targetColumn(); 13165 target.setId(String.valueOf(procedure.getId())); 13166 target.setName(getProcedureName(procedure)); 13167 if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) { 13168 target.setCoordinate(convertCoordinate(procedure.getStartPosition()) + "," 13169 + convertCoordinate(procedure.getEndPosition())); 13170 } 13171 String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase(); 13172 if (clazz.indexOf("function") != -1) { 13173 target.setType("function"); 13174 } else if (clazz.indexOf("trigger") != -1) { 13175 target.setType("trigger"); 13176 } else if (clazz.indexOf("macro") != -1) { 13177 target.setType("macro"); 13178 } else { 13179 target.setType("procedure"); 13180 } 13181 relationElement.setCaller(target); 13182 } else { 13183 continue; 13184 } 13185 13186 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)callRelation.getSources(); 13187 if (sourceElements.size() == 0) { 13188 continue; 13189 } 13190 13191 boolean append = false; 13192 for (RelationshipElement<?> sourceItem: sourceElements) { 13193 Object sourceElement = sourceItem.getElement(); 13194 if (sourceElement instanceof Procedure) { 13195 Procedure procedure = (Procedure) sourceElement; 13196 sourceColumn source = new sourceColumn(); 13197 source.setId(String.valueOf(procedure.getId())); 13198 source.setName(getProcedureName(procedure)); 13199 if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) { 13200 source.setCoordinate(convertCoordinate(procedure.getStartPosition()) + "," 13201 + convertCoordinate(procedure.getEndPosition())); 13202 } 13203 String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase(); 13204 if (clazz.indexOf("function") != -1) { 13205 source.setType("function"); 13206 } else if (clazz.indexOf("trigger") != -1) { 13207 source.setType("trigger"); 13208 } else if (clazz.indexOf("macro") != -1) { 13209 source.setType("macro"); 13210 } else { 13211 source.setType("procedure"); 13212 } 13213 append = true; 13214 relationElement.getCallees().add(source); 13215 } else if (sourceElement instanceof Function) { 13216 Function function = (Function) sourceElement; 13217 sourceColumn source = new sourceColumn(); 13218 source.setId(String.valueOf(function.getId())); 13219 source.setName(getFunctionName(function.getFunctionObject())); 13220 if (function.getStartPosition() != null && function.getEndPosition() != null) { 13221 source.setCoordinate(convertCoordinate(function.getStartPosition()) + "," 13222 + convertCoordinate(function.getEndPosition())); 13223 } 13224 source.setType("function"); 13225 append = true; 13226 relationElement.getCallees().add(source); 13227 } 13228 } 13229 13230 if (append) 13231 dataflow.getRelationships().add(relationElement); 13232 } 13233 } 13234 } 13235 13236 private void appendResultSets(dataflow dataflow) { 13237 Set<ResultSet> resultSets = modelManager.getResultSets(); 13238 for (ResultSet resultSet: resultSets) { 13239 appendResultSet(dataflow, resultSet); 13240 } 13241 } 13242 13243 private void appendResultSet(dataflow dataflow, ResultSet resultSetModel) { 13244 if (!appendResultSets.contains(resultSetModel)) { 13245 appendResultSets.add(resultSetModel); 13246 } else { 13247 return; 13248 } 13249 13250 table resultSetElement = new table(); 13251 resultSetElement.setId(String.valueOf(resultSetModel.getId())); 13252 resultSetElement.setServer(resultSetModel.getServer()); 13253 if (!SQLUtil.isEmpty(resultSetModel.getDatabase())) { 13254 resultSetElement.setDatabase(resultSetModel.getDatabase()); 13255 } 13256 if (!SQLUtil.isEmpty(resultSetModel.getSchema())) { 13257 resultSetElement.setSchema(resultSetModel.getSchema()); 13258 } 13259 resultSetElement.setName(getResultSetName(resultSetModel)); 13260 resultSetElement.setType(getResultSetType(resultSetModel)); 13261 // if ((ignoreRecordSet || simpleOutput) && resultSetModel.isTarget()) { 13262 resultSetElement.setIsTarget(String.valueOf(resultSetModel.isTarget())); 13263 // } 13264 resultSetElement.setIsDetermined(String.valueOf(resultSetModel.isDetermined())); 13265 if (resultSetModel.getStartPosition() != null && resultSetModel.getEndPosition() != null) { 13266 resultSetElement.setCoordinate(convertCoordinate(resultSetModel.getStartPosition()) + "," 13267 + convertCoordinate(resultSetModel.getEndPosition())); 13268 } 13269 dataflow.getResultsets().add(resultSetElement); 13270 13271 List<ResultColumn> columns = resultSetModel.getColumns(); 13272 13273 Map<String, Integer> columnCounts = new HashMap<String, Integer>(); 13274 for (ResultColumn column : columns) { 13275 String columnName = DlineageUtil.getIdentifierNormalColumnName(column.getName()); 13276 if (!columnCounts.containsKey(columnName)) { 13277 columnCounts.put(columnName, 0); 13278 } 13279 columnCounts.put(columnName, columnCounts.get(columnName) + 1); 13280 // if (column.hasStarLinkColumn()) { 13281 // List<String> starLinkColumns = column.getStarLinkColumnNames(); 13282 // for (int k = 0; k < starLinkColumns.size(); k++) { 13283 // columnName = starLinkColumns.get(k); 13284 // if (!columnCounts.containsKey(columnName)) { 13285 // columnCounts.put(columnName, 0); 13286 // } 13287 // columnCounts.put(columnName, columnCounts.get(columnName) + 1); 13288 // } 13289 // } 13290 } 13291 13292 for (int j = 0; j < columns.size(); j++) { 13293 ResultColumn columnModel = columns.get(j); 13294 if (columnModel.hasStarLinkColumn()) { 13295 // List<String> starLinkColumns = 13296 // columnModel.getStarLinkColumnNames(); 13297 // for (int k = 0; k < starLinkColumns.size(); k++) { 13298 // column columnElement = new column(); 13299 // columnElement.setId( String.valueOf(columnModel.getId()) + 13300 // "_" + k); 13301 // String columnName = starLinkColumns.get(k); 13302 // columnElement.setName(columnName); 13303 // if(columnModel.isFunction()){ 13304 // columnElement.setIsFunction(String.valueOf(columnModel.isFunction())); 13305 // } 13306 // if (columnModel.getStartPosition() != null && 13307 // columnModel.getEndPosition() != null) { 13308 // columnElement.setCoordinate( 13309 // columnModel.getStartPosition() + "," + 13310 // columnModel.getEndPosition()); 13311 // } 13312 // String identifier = columnName; 13313 // if(columnCounts.containsKey(identifier) && 13314 // columnCounts.get(identifier)>1){ 13315 // TObjectName column = 13316 // columnModel.getStarLinkColumns().get(columnName).iterator().next(); 13317 // if(!SQLUtil.isEmpty(getQualifiedTable(column))){ 13318 // columnElement.setQualifiedTable(getQualifiedTable(column)); 13319 // } 13320 // } 13321 // resultSetElement.getColumns().add(columnElement); 13322 // } 13323 if (columnModel.isShowStar()) { 13324 column columnElement = new column(); 13325 columnElement.setId(String.valueOf(columnModel.getId())); 13326 columnElement.setName(columnModel.getName()); 13327 if (columnModel.isFunction()) { 13328 columnElement.setIsFunction(String.valueOf(columnModel.isFunction())); 13329 } 13330 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 13331 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 13332 + convertCoordinate(columnModel.getEndPosition())); 13333 } 13334 13335 String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()); 13336 if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) { 13337 String qualifiedTable = getQualifiedTable(columnModel); 13338 if (!SQLUtil.isEmpty(qualifiedTable)) { 13339 columnElement.setQualifiedTable(qualifiedTable); 13340 } 13341 } 13342 resultSetElement.getColumns().add(columnElement); 13343 } 13344 } else { 13345 column columnElement = new column(); 13346 columnElement.setId(String.valueOf(columnModel.getId())); 13347 columnElement.setName(columnModel.getName()); 13348 if (columnModel.isFunction()) { 13349 columnElement.setIsFunction(String.valueOf(columnModel.isFunction())); 13350 } 13351 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 13352 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 13353 + convertCoordinate(columnModel.getEndPosition())); 13354 } 13355 13356 String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()); 13357 if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) { 13358 String qualifiedTable = getQualifiedTable(columnModel); 13359 if (!SQLUtil.isEmpty(qualifiedTable)) { 13360 columnElement.setQualifiedTable(qualifiedTable); 13361 } 13362 } 13363 resultSetElement.getColumns().add(columnElement); 13364 } 13365 } 13366 13367 ResultSetRelationRows relationRows = resultSetModel.getRelationRows(); 13368 if (relationRows.hasRelation()) { 13369 column relationRowsElement = new column(); 13370 relationRowsElement.setId(String.valueOf(relationRows.getId())); 13371 relationRowsElement.setName(relationRows.getName()); 13372 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 13373 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 13374 + convertCoordinate(relationRows.getEndPosition())); 13375 } 13376 relationRowsElement.setSource("system"); 13377 resultSetElement.getColumns().add(relationRowsElement); 13378 } 13379 } 13380 13381 private String getQualifiedTable(ResultColumn columnModel) { 13382 if (columnModel.getColumnObject() instanceof TObjectName) { 13383 return getQualifiedTable((TObjectName) columnModel.getColumnObject()); 13384 } 13385 if (columnModel.getColumnObject() instanceof TResultColumn) { 13386 TObjectName field = ((TResultColumn) columnModel.getColumnObject()).getFieldAttr(); 13387 if (field != null) { 13388 return getQualifiedTable(field); 13389 } 13390 } 13391 return null; 13392 } 13393 13394 private String getQualifiedTable(TObjectName column) { 13395 if (column == null) 13396 return null; 13397 String[] splits = column.toString().split("\\."); 13398 if (splits.length > 1) { 13399 return splits[splits.length - 2]; 13400 } 13401 return null; 13402 } 13403 13404 /** 13405 * Get the qualified prefix (schema.table) from a column name for 3-part names. 13406 * For example, for "sch.pk_constv2.c_cdsl", returns "sch.pk_constv2". 13407 * Returns null if the column doesn't have both schema and table parts. 13408 */ 13409 private String getQualifiedPrefixFromColumn(TObjectName column) { 13410 if (column == null) return null; 13411 13412 // Check if both schema and table tokens are present (3-part name) 13413 String schemaStr = column.getSchemaString(); 13414 String tableStr = column.getTableString(); 13415 13416 if (schemaStr != null && !schemaStr.isEmpty() && 13417 tableStr != null && !tableStr.isEmpty()) { 13418 return schemaStr + "." + tableStr; 13419 } 13420 13421 // Fallback: parse from toString() for complex cases 13422 String[] splits = column.toString().split("\\."); 13423 if (splits.length >= 3) { 13424 // Return all parts except the last one (column name) 13425 StringBuilder prefix = new StringBuilder(); 13426 for (int i = 0; i < splits.length - 1; i++) { 13427 if (i > 0) prefix.append("."); 13428 prefix.append(splits[i]); 13429 } 13430 return prefix.toString(); 13431 } 13432 13433 return null; 13434 } 13435 13436 private String getResultSetType(ResultSet resultSetModel) { 13437 if (resultSetModel instanceof QueryTable) { 13438 QueryTable table = (QueryTable) resultSetModel; 13439 if (table.getTableObject().getCTE() != null) { 13440 return "with_cte"; 13441 } 13442 } 13443 13444 if (resultSetModel instanceof SelectSetResultSet) { 13445 ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType(); 13446 return "select_" + type.name(); 13447 } 13448 13449 if (resultSetModel instanceof SelectResultSet) { 13450 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) { 13451 return "insert-select"; 13452 } 13453 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) { 13454 return "update-select"; 13455 } 13456 } 13457 13458 if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) { 13459 return "merge-update"; 13460 } 13461 13462 if (resultSetModel.getGspObject() instanceof TOutputClause) { 13463 return ResultSetType.output.name(); 13464 } 13465 13466 if (resultSetModel.getGspObject() instanceof TMergeInsertClause) { 13467 return "merge-insert"; 13468 } 13469 13470 if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) { 13471 return "update-set"; 13472 } 13473 13474 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) { 13475 return ResultSetType.array.name(); 13476 } 13477 13478 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) { 13479 return ResultSetType.struct.name(); 13480 } 13481 13482 if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) { 13483 return ResultSetType.function.name(); 13484 } 13485 13486 if (resultSetModel.getGspObject() instanceof TAliasClause) { 13487 return ResultSetType.alias.name(); 13488 } 13489 13490 if (resultSetModel.getGspObject() instanceof TCursorDeclStmt) { 13491 return ResultSetType.cursor.name(); 13492 } 13493 13494 if (resultSetModel instanceof PivotedTable) { 13495 if (((PivotedTable) resultSetModel).isUnpivoted()) { 13496 return ResultSetType.unpivot_table.name(); 13497 } 13498 return ResultSetType.pivot_table.name(); 13499 } 13500 13501 return "select_list"; 13502 } 13503 13504 private String getTableName(Table tableModel) { 13505 if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) { 13506 return modelManager.DISPLAY_NAME.get(tableModel.getId()); 13507 } 13508 13509 String tableName; 13510 if (tableModel.getFullName() != null && tableModel.getFullName().trim().length() > 0) { 13511 return tableModel.getFullName(); 13512 } 13513 if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) { 13514 tableName = getResultSetWithId("RESULT_OF_" + tableModel.getAlias()); 13515 13516 } else { 13517 tableName = getResultSetDisplayId("RS"); 13518 } 13519 modelManager.DISPLAY_NAME.put(tableModel.getId(), tableName); 13520 return tableName; 13521 } 13522 13523 private String getProcedureName(Procedure procedureModel) { 13524 if (modelManager.DISPLAY_NAME.containsKey(procedureModel.getId())) { 13525 return modelManager.DISPLAY_NAME.get(procedureModel.getId()); 13526 } 13527 13528 String procedureName = procedureModel.getFullName(); 13529 13530 modelManager.DISPLAY_NAME.put(procedureModel.getId(), procedureName); 13531 return procedureName; 13532 } 13533 13534 private String getProcessName(Process processModel) { 13535 if (modelManager.DISPLAY_NAME.containsKey(processModel.getId())) { 13536 return modelManager.DISPLAY_NAME.get(processModel.getId()); 13537 } else { 13538 if (processModel.getCustomType() != null) { 13539 String name = processModel.getCustomType(); 13540 modelManager.DISPLAY_NAME.put(processModel.getId(), name); 13541 return name; 13542 } 13543 String name = processModel.getType(); 13544 String procedureName = getProcedureParentName(processModel.getGspObject()); 13545 if (procedureName != null) { 13546 name = getResultSetDisplayId(procedureName + " " + name); 13547 } else { 13548 name = getResultSetDisplayId("Query " + name); 13549 } 13550 modelManager.DISPLAY_NAME.put(processModel.getId(), name); 13551 return name; 13552 } 13553 } 13554 13555 private String getDisplayIdByType(String type) { 13556 if (!modelManager.DISPLAY_ID.containsKey(type)) { 13557 modelManager.DISPLAY_ID.put(type, option.getStartId() + 1); 13558 return type + "-" + (option.getStartId() + 1); 13559 } else { 13560 long id = modelManager.DISPLAY_ID.get(type); 13561 modelManager.DISPLAY_ID.put(type, id + 1); 13562 return type + "-" + (id + 1); 13563 } 13564 } 13565 13566 private String getDisplayIdByTypeFromZero(String type) { 13567 if (!modelManager.DISPLAY_ID.containsKey(type)) { 13568 modelManager.DISPLAY_ID.put(type, option.getStartId()); 13569 if(option.getStartId() == 0) { 13570 return type; 13571 } 13572 return type + "-" + (option.getStartId() + 1); 13573 } else { 13574 long id = modelManager.DISPLAY_ID.get(type); 13575 modelManager.DISPLAY_ID.put(type, id + 1); 13576 return type + "-" + (id + 1); 13577 } 13578 } 13579 13580 private String getConstantName(Table tableModel) { 13581 if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) { 13582 return modelManager.DISPLAY_NAME.get(tableModel.getId()); 13583 } else { 13584 String name = getDisplayIdByType("SQL_CONSTANTS"); 13585 modelManager.DISPLAY_NAME.put(tableModel.getId(), name); 13586 return name; 13587 } 13588 } 13589 13590 private String getTempTableName(TTable table) { 13591 if (modelManager.DISPLAY_NAME.containsKey((long)System.identityHashCode(table))) { 13592 return modelManager.DISPLAY_NAME.get((long)System.identityHashCode(table)); 13593 } else { 13594 String name = getDisplayIdByTypeFromZero(table.getName()); 13595 modelManager.DISPLAY_NAME.put((long)System.identityHashCode(table), name); 13596 return name; 13597 } 13598 } 13599 13600 private String getResultSetName(ResultSet resultSetModel) { 13601 13602 if (modelManager.DISPLAY_NAME.containsKey(resultSetModel.getId())) { 13603 return modelManager.DISPLAY_NAME.get(resultSetModel.getId()); 13604 } 13605 13606 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) { 13607 String name = getResultSetDisplayId("ARRAY"); 13608 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13609 if(option.containsResultSetType(ResultSetType.array)) { 13610 resultSetModel.setTarget(true); 13611 } 13612 return name; 13613 } 13614 13615 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) { 13616 String name = getResultSetDisplayId("STRUCT"); 13617 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13618 if(option.containsResultSetType(ResultSetType.struct)) { 13619 resultSetModel.setTarget(true); 13620 } 13621 return name; 13622 } 13623 13624 if (resultSetModel instanceof QueryTable) { 13625 QueryTable table = (QueryTable) resultSetModel; 13626 if (table.getAlias() != null && table.getAlias().trim().length() > 0) { 13627 String name = getResultSetWithId("RESULT_OF_" + table.getAlias().trim()); 13628 if (table.getTableObject().getCTE() != null) { 13629 name = getResultSetWithId("RESULT_OF_" + table.getTableObject().getCTE().getTableName().toString() 13630 + "_" + table.getAlias().trim()); 13631 } 13632 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13633 if(option.containsResultSetType(ResultSetType.result_of)) { 13634 resultSetModel.setTarget(true); 13635 } 13636 return name; 13637 } else if (table.getTableObject().getCTE() != null) { 13638 String name = getResultSetWithId("CTE-" + table.getTableObject().getCTE().getTableName().toString()); 13639 modelManager.DISPLAY_NAME.put(table.getId(), name); 13640 if(option.containsResultSetType(ResultSetType.cte)) { 13641 resultSetModel.setTarget(true); 13642 } 13643 return name; 13644 } 13645 } 13646 13647 if (resultSetModel instanceof SelectResultSet) { 13648 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) { 13649 String name = getResultSetDisplayId("INSERT-SELECT"); 13650 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13651 if(option.containsResultSetType(ResultSetType.insert_select)) { 13652 resultSetModel.setTarget(true); 13653 } 13654 return name; 13655 } 13656 13657 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) { 13658 String name = getResultSetDisplayId("UPDATE-SELECT"); 13659 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13660 if(option.containsResultSetType(ResultSetType.update_select)) { 13661 resultSetModel.setTarget(true); 13662 } 13663 return name; 13664 } 13665 } 13666 13667 if (resultSetModel instanceof SelectSetResultSet) { 13668 ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType(); 13669 String name = getResultSetDisplayId("RESULT_OF_" + type.name().toUpperCase()); 13670 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13671 if(option.containsResultSetType(ResultSetType.result_of)) { 13672 resultSetModel.setTarget(true); 13673 } 13674 return name; 13675 } 13676 13677 if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) { 13678 String name = getResultSetDisplayId("MERGE-UPDATE"); 13679 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13680 if(option.containsResultSetType(ResultSetType.merge_update)) { 13681 resultSetModel.setTarget(true); 13682 } 13683 return name; 13684 } 13685 13686 if (resultSetModel.getGspObject() instanceof TOutputClause) { 13687 String name = getResultSetDisplayId("OUTPUT"); 13688 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13689 if(option.containsResultSetType(ResultSetType.output)) { 13690 resultSetModel.setTarget(true); 13691 } 13692 return name; 13693 } 13694 13695 if (resultSetModel.getGspObject() instanceof TMergeInsertClause) { 13696 String name = getResultSetDisplayId("MERGE-INSERT"); 13697 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13698 if(option.containsResultSetType(ResultSetType.merge_insert)) { 13699 resultSetModel.setTarget(true); 13700 } 13701 return name; 13702 } 13703 13704 if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) { 13705 String name = getResultSetDisplayId("UPDATE-SET"); 13706 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13707 if(option.containsResultSetType(ResultSetType.update_set)) { 13708 resultSetModel.setTarget(true); 13709 } 13710 return name; 13711 } 13712 13713 if (resultSetModel.getGspObject() instanceof TCaseExpression) { 13714 String name = ((Function) resultSetModel).getFunctionName(); 13715 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13716 if (option.containsResultSetType(ResultSetType.case_when) || option.containsResultSetType(ResultSetType.function)) { 13717 resultSetModel.setTarget(true); 13718 } 13719 return name; 13720 } 13721 13722 if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) { 13723 String name = ((Function) resultSetModel).getFunctionName(); 13724 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13725 if(option.containsResultSetType(ResultSetType.function)) { 13726 resultSetModel.setTarget(true); 13727 } 13728 return name; 13729 } 13730 13731 if (resultSetModel instanceof PivotedTable) { 13732 String name = getResultSetDisplayId("PIVOT-TABLE"); 13733 if (((PivotedTable) resultSetModel).isUnpivoted()) { 13734 name = getResultSetDisplayId("UNPIVOT-TABLE"); 13735 if(option.containsResultSetType(ResultSetType.unpivot_table)) { 13736 resultSetModel.setTarget(true); 13737 } 13738 } 13739 else { 13740 if(option.containsResultSetType(ResultSetType.pivot_table)) { 13741 resultSetModel.setTarget(true); 13742 } 13743 } 13744 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13745 return name; 13746 } 13747 13748 if (resultSetModel instanceof Alias) { 13749 String name = getResultSetDisplayId("ALIAS"); 13750 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13751 if(option.containsResultSetType(ResultSetType.alias)) { 13752 resultSetModel.setTarget(true); 13753 } 13754 return name; 13755 } 13756 13757 String name = getResultSetDisplayId("RS"); 13758 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 13759 if(option.containsResultSetType(ResultSetType.select_list)) { 13760 resultSetModel.setTarget(true); 13761 } 13762 return name; 13763 } 13764 13765 private String getResultSetWithId(String type) { 13766 type = DlineageUtil.getIdentifierNormalTableName(type); 13767 if (!modelManager.DISPLAY_ID.containsKey(type)) { 13768 modelManager.DISPLAY_ID.put(type, option.getStartId() + 1); 13769 return type + "-" + (option.getStartId() + 1); 13770 } else { 13771 long id = modelManager.DISPLAY_ID.get(type); 13772 modelManager.DISPLAY_ID.put(type, id + 1); 13773 return type + "-" + (id + 1); 13774 } 13775 } 13776 13777 private String getResultSetDisplayId(String type) { 13778 if (!modelManager.DISPLAY_ID.containsKey(type)) { 13779 modelManager.DISPLAY_ID.put(type, option.getStartId() + 1); 13780 return type + "-" + (option.getStartId() + 1); 13781 } else { 13782 long id = modelManager.DISPLAY_ID.get(type); 13783 modelManager.DISPLAY_ID.put(type, id + 1); 13784 return type + "-" + (id + 1); 13785 } 13786 } 13787 13788 private void appendViews(dataflow dataflow) { 13789 List<TCustomSqlStatement> views = modelManager.getViews(); 13790 for (int i = 0; i < views.size(); i++) { 13791 Table viewModel = (Table) modelManager.getViewModel(views.get(i)); 13792 if (!tableIds.contains(viewModel.getId())) { 13793 appendViewModel(dataflow, viewModel); 13794 tableIds.add(viewModel.getId()); 13795 } 13796 } 13797 13798 List<TTable> tables = modelManager.getBaseTables(); 13799 for (int i = 0; i < tables.size(); i++) { 13800 Object model = modelManager.getModel(tables.get(i)); 13801 if (model instanceof Table) { 13802 Table tableModel = (Table) model; 13803 if (tableModel.isView()) { 13804 if (!tableIds.contains(tableModel.getId())) { 13805 appendViewModel(dataflow, tableModel); 13806 tableIds.add(tableModel.getId()); 13807 } 13808 } 13809 } 13810 } 13811 13812 List<Table> tableNames = modelManager.getTablesByName(); 13813 for (int i = 0; i < tableNames.size(); i++) { 13814 Table tableModel = tableNames.get(i); 13815 if (tableModel.isView()) { 13816 if (!tableIds.contains(tableModel.getId())) { 13817 appendViewModel(dataflow, tableModel); 13818 tableIds.add(tableModel.getId()); 13819 } 13820 } 13821 } 13822 } 13823 13824 private void appendViewModel(dataflow dataflow, Table viewModel) { 13825 table viewElement = new table(); 13826 viewElement.setId(String.valueOf(viewModel.getId())); 13827 if (!SQLUtil.isEmpty(viewModel.getDatabase())) { 13828 viewElement.setDatabase(viewModel.getDatabase()); 13829 } 13830 if (!SQLUtil.isEmpty(viewModel.getSchema())) { 13831 viewElement.setSchema(viewModel.getSchema()); 13832 } 13833 viewElement.setServer(viewModel.getServer()); 13834 viewElement.setName(viewModel.getName()); 13835 viewElement.setType("view"); 13836 viewElement.setStarStmt(viewModel.getStarStmt()); 13837 13838 if(viewModel.isFromDDL()){ 13839 viewElement.setFromDDL(String.valueOf(viewModel.isFromDDL())); 13840 } 13841 13842 if(option.isTraceTablePosition()){ 13843 for (Pair<Pair3<Long, Long, String>, Pair3<Long, Long, String>> position:viewModel.getPositions()){ 13844 viewElement.setCoordinate(convertCoordinate(position.first)+","+convertCoordinate(position.second)); 13845 } 13846 } 13847 else { 13848 viewElement.setCoordinate(convertCoordinate(viewModel.getStartPosition()) + "," 13849 + convertCoordinate(viewModel.getEndPosition())); 13850 } 13851 13852 if (viewModel.getProcesses() != null) { 13853 List<String> processIds = new ArrayList<String>(); 13854 for (Process process : viewModel.getProcesses()) { 13855 processIds.add(String.valueOf(process.getId())); 13856 } 13857 viewElement.setProcessIds(processIds); 13858 } 13859 dataflow.getViews().add(viewElement); 13860 13861 List<TableColumn> columns = viewModel.getColumns(); 13862 13863 if (containStarColumn(columns)) { 13864 for (TableColumn column : columns) { 13865 if (column.getName().endsWith("*")) { 13866 for (TableColumn starElement : columns) { 13867 if (starElement == column) { 13868 continue; 13869 } 13870 TObjectName columnObject = starElement.getColumnObject(); 13871 column.bindStarLinkColumn(columnObject); 13872 } 13873 if (viewModel.isCreateTable()) { 13874 column.setShowStar(false); 13875 } 13876 } 13877 } 13878 } 13879 13880 for (int j = 0; j < columns.size(); j++) { 13881 TableColumn columnModel = (TableColumn) columns.get(j); 13882 if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn()) { 13883 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 13884 for (int k = 0; k < starLinkColumnList.size(); k++) { 13885 column columnElement = new column(); 13886 columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k); 13887 String columnName = starLinkColumnList.get(k); 13888 if (containStarColumn(columns, columnName)) { 13889 continue; 13890 } 13891 columnElement.setName(columnName); 13892 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 13893 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 13894 + convertCoordinate(columnModel.getEndPosition())); 13895 } 13896 viewElement.getColumns().add(columnElement); 13897 } 13898 13899 if (columnModel.isShowStar()) { 13900 column columnElement = new column(); 13901 columnElement.setId(String.valueOf(columnModel.getId())); 13902 columnElement.setName(columnModel.getName()); 13903 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 13904 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 13905 + convertCoordinate(columnModel.getEndPosition())); 13906 } 13907 viewElement.getColumns().add(columnElement); 13908 } 13909 13910 } else { 13911 column columnElement = new column(); 13912 columnElement.setId(String.valueOf(columnModel.getId())); 13913 columnElement.setName(columnModel.getName()); 13914 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 13915 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 13916 + convertCoordinate(columnModel.getEndPosition())); 13917 } 13918 if(columnModel.isPseduo()) { 13919 columnElement.setSource("system"); 13920 } 13921 viewElement.getColumns().add(columnElement); 13922 } 13923 } 13924 13925 TableRelationRows relationRows = viewModel.getRelationRows(); 13926 if (relationRows.hasRelation()) { 13927 column relationRowsElement = new column(); 13928 relationRowsElement.setId(String.valueOf(relationRows.getId())); 13929 relationRowsElement.setName(relationRows.getName()); 13930 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 13931 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 13932 + convertCoordinate(relationRows.getEndPosition())); 13933 } 13934 relationRowsElement.setSource("system"); 13935 viewElement.getColumns().add(relationRowsElement); 13936 } 13937 } 13938 13939 private void appendStreamModel(dataflow dataflow, Table streamModel) { 13940 table streamElement = new table(); 13941 streamElement.setId(String.valueOf(streamModel.getId())); 13942 if (!SQLUtil.isEmpty(streamModel.getDatabase())) { 13943 streamElement.setDatabase(streamModel.getDatabase()); 13944 } 13945 if (!SQLUtil.isEmpty(streamModel.getSchema())) { 13946 streamElement.setSchema(streamModel.getSchema()); 13947 } 13948 streamElement.setServer(streamModel.getServer()); 13949 streamElement.setName(streamModel.getName()); 13950 streamElement.setType("stream"); 13951 if (streamModel.getFileType() != null) { 13952 streamElement.setFileType(SQLUtil.trimColumnStringQuote(streamModel.getFileType())); 13953 } 13954 13955 if (streamModel.getStartPosition() != null && streamModel.getEndPosition() != null) { 13956 streamElement.setCoordinate(convertCoordinate(streamModel.getStartPosition()) + "," 13957 + convertCoordinate(streamModel.getEndPosition())); 13958 } 13959 13960 if (streamModel.getProcesses() != null) { 13961 List<String> processIds = new ArrayList<String>(); 13962 for (Process process : streamModel.getProcesses()) { 13963 processIds.add(String.valueOf(process.getId())); 13964 } 13965 streamElement.setProcessIds(processIds); 13966 } 13967 dataflow.getStreams().add(streamElement); 13968 13969 List<TableColumn> columns = streamModel.getColumns(); 13970 13971 for (int j = 0; j < columns.size(); j++) { 13972 TableColumn columnModel = (TableColumn) columns.get(j); 13973 column columnElement = new column(); 13974 columnElement.setId(String.valueOf(columnModel.getId())); 13975 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 13976 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 13977 + convertCoordinate(columnModel.getEndPosition())); 13978 streamElement.getColumns().add(columnElement); 13979 } 13980 13981 TableRelationRows relationRows = streamModel.getRelationRows(); 13982 if (relationRows.hasRelation()) { 13983 column relationRowsElement = new column(); 13984 relationRowsElement.setId(String.valueOf(relationRows.getId())); 13985 relationRowsElement.setName(relationRows.getName()); 13986 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 13987 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 13988 + convertCoordinate(relationRows.getEndPosition())); 13989 } 13990 relationRowsElement.setSource("system"); 13991 streamElement.getColumns().add(relationRowsElement); 13992 } 13993 } 13994 13995 private void appendStageModel(dataflow dataflow, Table stageModel) { 13996 table stageElement = new table(); 13997 stageElement.setId(String.valueOf(stageModel.getId())); 13998 if (!SQLUtil.isEmpty(stageModel.getDatabase())) { 13999 stageElement.setDatabase(stageModel.getDatabase()); 14000 } 14001 if (!SQLUtil.isEmpty(stageModel.getSchema())) { 14002 stageElement.setSchema(stageModel.getSchema()); 14003 } 14004 stageElement.setServer(stageModel.getServer()); 14005 stageElement.setName(stageModel.getName()); 14006 stageElement.setType("stage"); 14007 stageElement.setLocation(stageModel.getLocation()); 14008 if (stageModel.getFileType() != null) { 14009 stageElement.setFileType(SQLUtil.trimColumnStringQuote(stageModel.getFileType())); 14010 } 14011 14012 if (stageModel.getStartPosition() != null && stageModel.getEndPosition() != null) { 14013 stageElement.setCoordinate(convertCoordinate(stageModel.getStartPosition()) + "," 14014 + convertCoordinate(stageModel.getEndPosition())); 14015 } 14016 14017 if (stageModel.getProcesses() != null) { 14018 List<String> processIds = new ArrayList<String>(); 14019 for (Process process : stageModel.getProcesses()) { 14020 processIds.add(String.valueOf(process.getId())); 14021 } 14022 stageElement.setProcessIds(processIds); 14023 } 14024 dataflow.getStages().add(stageElement); 14025 14026 List<TableColumn> columns = stageModel.getColumns(); 14027 14028 for (int j = 0; j < columns.size(); j++) { 14029 TableColumn columnModel = (TableColumn) columns.get(j); 14030 column columnElement = new column(); 14031 columnElement.setId(String.valueOf(columnModel.getId())); 14032 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14033 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14034 + convertCoordinate(columnModel.getEndPosition())); 14035 stageElement.getColumns().add(columnElement); 14036 } 14037 14038 TableRelationRows relationRows = stageModel.getRelationRows(); 14039 if (relationRows.hasRelation()) { 14040 column relationRowsElement = new column(); 14041 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14042 relationRowsElement.setName(relationRows.getName()); 14043 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14044 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14045 + convertCoordinate(relationRows.getEndPosition())); 14046 } 14047 relationRowsElement.setSource("system"); 14048 stageElement.getColumns().add(relationRowsElement); 14049 } 14050 } 14051 14052 private void appendSequenceModel(dataflow dataflow, Table sequenceModel) { 14053 table sequenceElement = new table(); 14054 sequenceElement.setId(String.valueOf(sequenceModel.getId())); 14055 if (!SQLUtil.isEmpty(sequenceModel.getDatabase())) { 14056 sequenceElement.setDatabase(sequenceModel.getDatabase()); 14057 } 14058 if (!SQLUtil.isEmpty(sequenceModel.getSchema())) { 14059 sequenceElement.setSchema(sequenceModel.getSchema()); 14060 } 14061 sequenceElement.setServer(sequenceModel.getServer()); 14062 sequenceElement.setName(sequenceModel.getName()); 14063 sequenceElement.setType("sequence"); 14064 sequenceElement.setLocation(sequenceModel.getLocation()); 14065 if (sequenceModel.getFileType() != null) { 14066 sequenceElement.setFileType(SQLUtil.trimColumnStringQuote(sequenceModel.getFileType())); 14067 } 14068 14069 if (sequenceModel.getStartPosition() != null && sequenceModel.getEndPosition() != null) { 14070 sequenceElement.setCoordinate(convertCoordinate(sequenceModel.getStartPosition()) + "," 14071 + convertCoordinate(sequenceModel.getEndPosition())); 14072 } 14073 14074 if (sequenceModel.getProcesses() != null) { 14075 List<String> processIds = new ArrayList<String>(); 14076 for (Process process : sequenceModel.getProcesses()) { 14077 processIds.add(String.valueOf(process.getId())); 14078 } 14079 sequenceElement.setProcessIds(processIds); 14080 } 14081 dataflow.getSequences().add(sequenceElement); 14082 14083 List<TableColumn> columns = sequenceModel.getColumns(); 14084 14085 for (int j = 0; j < columns.size(); j++) { 14086 TableColumn columnModel = (TableColumn) columns.get(j); 14087 column columnElement = new column(); 14088 columnElement.setId(String.valueOf(columnModel.getId())); 14089 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14090 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14091 + convertCoordinate(columnModel.getEndPosition())); 14092 sequenceElement.getColumns().add(columnElement); 14093 } 14094 14095 TableRelationRows relationRows = sequenceModel.getRelationRows(); 14096 if (relationRows.hasRelation()) { 14097 column relationRowsElement = new column(); 14098 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14099 relationRowsElement.setName(relationRows.getName()); 14100 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14101 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14102 + convertCoordinate(relationRows.getEndPosition())); 14103 } 14104 relationRowsElement.setSource("system"); 14105 sequenceElement.getColumns().add(relationRowsElement); 14106 } 14107 } 14108 14109 private void appendDataSourceModel(dataflow dataflow, Table datasourceModel) { 14110 table datasourceElement = new table(); 14111 datasourceElement.setId(String.valueOf(datasourceModel.getId())); 14112 if (!SQLUtil.isEmpty(datasourceModel.getDatabase())) { 14113 datasourceElement.setDatabase(datasourceModel.getDatabase()); 14114 } 14115 if (!SQLUtil.isEmpty(datasourceModel.getSchema())) { 14116 datasourceElement.setSchema(datasourceModel.getSchema()); 14117 } 14118 datasourceElement.setServer(datasourceModel.getServer()); 14119 datasourceElement.setName(datasourceModel.getName()); 14120 datasourceElement.setType("datasource"); 14121 datasourceElement.setLocation(datasourceModel.getLocation()); 14122 if (datasourceModel.getFileType() != null) { 14123 datasourceElement.setFileType(SQLUtil.trimColumnStringQuote(datasourceModel.getFileType())); 14124 } 14125 14126 if (datasourceModel.getStartPosition() != null && datasourceModel.getEndPosition() != null) { 14127 datasourceElement.setCoordinate(convertCoordinate(datasourceModel.getStartPosition()) + "," 14128 + convertCoordinate(datasourceModel.getEndPosition())); 14129 } 14130 14131 if (datasourceModel.getProcesses() != null) { 14132 List<String> processIds = new ArrayList<String>(); 14133 for (Process process : datasourceModel.getProcesses()) { 14134 processIds.add(String.valueOf(process.getId())); 14135 } 14136 datasourceElement.setProcessIds(processIds); 14137 } 14138 dataflow.getDatasources().add(datasourceElement); 14139 14140 List<TableColumn> columns = datasourceModel.getColumns(); 14141 14142 for (int j = 0; j < columns.size(); j++) { 14143 TableColumn columnModel = (TableColumn) columns.get(j); 14144 column columnElement = new column(); 14145 columnElement.setId(String.valueOf(columnModel.getId())); 14146 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14147 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14148 + convertCoordinate(columnModel.getEndPosition())); 14149 datasourceElement.getColumns().add(columnElement); 14150 } 14151 14152 TableRelationRows relationRows = datasourceModel.getRelationRows(); 14153 if (relationRows.hasRelation()) { 14154 column relationRowsElement = new column(); 14155 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14156 relationRowsElement.setName(relationRows.getName()); 14157 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14158 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14159 + convertCoordinate(relationRows.getEndPosition())); 14160 } 14161 relationRowsElement.setSource("system"); 14162 datasourceElement.getColumns().add(relationRowsElement); 14163 } 14164 } 14165 14166 private void appendDatabaseModel(dataflow dataflow, Table databaseModel) { 14167 table databaseElement = new table(); 14168 databaseElement.setId(String.valueOf(databaseModel.getId())); 14169 if (!SQLUtil.isEmpty(databaseModel.getDatabase())) { 14170 databaseElement.setDatabase(databaseModel.getDatabase()); 14171 } 14172 if (!SQLUtil.isEmpty(databaseModel.getSchema())) { 14173 databaseElement.setSchema(databaseModel.getSchema()); 14174 } 14175 databaseElement.setServer(databaseModel.getServer()); 14176 databaseElement.setName(databaseModel.getName()); 14177 databaseElement.setType("database"); 14178 if (databaseModel.getFileType() != null) { 14179 databaseElement.setFileType(SQLUtil.trimColumnStringQuote(databaseModel.getFileType())); 14180 } 14181 14182 if (databaseModel.getStartPosition() != null && databaseModel.getEndPosition() != null) { 14183 databaseElement.setCoordinate(convertCoordinate(databaseModel.getStartPosition()) + "," 14184 + convertCoordinate(databaseModel.getEndPosition())); 14185 } 14186 14187 if (databaseModel.getProcesses() != null) { 14188 List<String> processIds = new ArrayList<String>(); 14189 for (Process process : databaseModel.getProcesses()) { 14190 processIds.add(String.valueOf(process.getId())); 14191 } 14192 databaseElement.setProcessIds(processIds); 14193 } 14194 dataflow.getDatabases().add(databaseElement); 14195 14196 List<TableColumn> columns = databaseModel.getColumns(); 14197 14198 for (int j = 0; j < columns.size(); j++) { 14199 TableColumn columnModel = (TableColumn) columns.get(j); 14200 column columnElement = new column(); 14201 columnElement.setId(String.valueOf(columnModel.getId())); 14202 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14203 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14204 + convertCoordinate(columnModel.getEndPosition())); 14205 databaseElement.getColumns().add(columnElement); 14206 } 14207 14208 TableRelationRows relationRows = databaseModel.getRelationRows(); 14209 if (relationRows.hasRelation()) { 14210 column relationRowsElement = new column(); 14211 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14212 relationRowsElement.setName(relationRows.getName()); 14213 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14214 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14215 + convertCoordinate(relationRows.getEndPosition())); 14216 } 14217 relationRowsElement.setSource("system"); 14218 databaseElement.getColumns().add(relationRowsElement); 14219 } 14220 } 14221 14222 private void appendSchemaModel(dataflow dataflow, Table schemaModel) { 14223 table schemaElement = new table(); 14224 schemaElement.setId(String.valueOf(schemaModel.getId())); 14225 if (!SQLUtil.isEmpty(schemaModel.getDatabase())) { 14226 schemaElement.setDatabase(schemaModel.getDatabase()); 14227 } 14228 if (!SQLUtil.isEmpty(schemaModel.getSchema())) { 14229 schemaElement.setSchema(schemaModel.getSchema()); 14230 } 14231 schemaElement.setServer(schemaModel.getServer()); 14232 schemaElement.setName(schemaModel.getName()); 14233 schemaElement.setType("schema"); 14234 if (schemaModel.getFileType() != null) { 14235 schemaElement.setFileType(SQLUtil.trimColumnStringQuote(schemaModel.getFileType())); 14236 } 14237 14238 if (schemaModel.getStartPosition() != null && schemaModel.getEndPosition() != null) { 14239 schemaElement.setCoordinate(convertCoordinate(schemaModel.getStartPosition()) + "," 14240 + convertCoordinate(schemaModel.getEndPosition())); 14241 } 14242 14243 if (schemaModel.getProcesses() != null) { 14244 List<String> processIds = new ArrayList<String>(); 14245 for (Process process : schemaModel.getProcesses()) { 14246 processIds.add(String.valueOf(process.getId())); 14247 } 14248 schemaElement.setProcessIds(processIds); 14249 } 14250 dataflow.getSchemas().add(schemaElement); 14251 14252 List<TableColumn> columns = schemaModel.getColumns(); 14253 14254 for (int j = 0; j < columns.size(); j++) { 14255 TableColumn columnModel = (TableColumn) columns.get(j); 14256 column columnElement = new column(); 14257 columnElement.setId(String.valueOf(columnModel.getId())); 14258 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14259 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14260 + convertCoordinate(columnModel.getEndPosition())); 14261 schemaElement.getColumns().add(columnElement); 14262 } 14263 14264 TableRelationRows relationRows = schemaModel.getRelationRows(); 14265 if (relationRows.hasRelation()) { 14266 column relationRowsElement = new column(); 14267 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14268 relationRowsElement.setName(relationRows.getName()); 14269 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14270 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14271 + convertCoordinate(relationRows.getEndPosition())); 14272 } 14273 relationRowsElement.setSource("system"); 14274 schemaElement.getColumns().add(relationRowsElement); 14275 } 14276 } 14277 14278 private void appendPathModel(dataflow dataflow, Table pathModel) { 14279 table pathElement = new table(); 14280 pathElement.setId(String.valueOf(pathModel.getId())); 14281 if (!SQLUtil.isEmpty(pathModel.getDatabase())) { 14282 pathElement.setDatabase(pathModel.getDatabase()); 14283 } 14284 if (!SQLUtil.isEmpty(pathModel.getSchema())) { 14285 pathElement.setSchema(pathModel.getSchema()); 14286 } 14287 pathElement.setServer(pathModel.getServer()); 14288 pathElement.setName(pathModel.getName()); 14289 pathElement.setType("path"); 14290 if (pathModel.getFileFormat() != null) { 14291 pathElement.setFileFormat(SQLUtil.trimColumnStringQuote(pathModel.getFileFormat())); 14292 } 14293 14294 if (pathModel.getStartPosition() != null && pathModel.getEndPosition() != null) { 14295 pathElement.setCoordinate(convertCoordinate(pathModel.getStartPosition()) + "," 14296 + convertCoordinate(pathModel.getEndPosition())); 14297 } 14298 14299 if (pathModel.getProcesses() != null) { 14300 List<String> processIds = new ArrayList<String>(); 14301 for (Process process : pathModel.getProcesses()) { 14302 processIds.add(String.valueOf(process.getId())); 14303 } 14304 pathElement.setProcessIds(processIds); 14305 } 14306 14307 pathElement.setUri(pathModel.getName()); 14308 14309 dataflow.getPaths().add(pathElement); 14310 14311 List<TableColumn> columns = pathModel.getColumns(); 14312 14313 for (int j = 0; j < columns.size(); j++) { 14314 TableColumn columnModel = (TableColumn) columns.get(j); 14315 column columnElement = new column(); 14316 columnElement.setId(String.valueOf(columnModel.getId())); 14317 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14318 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14319 + convertCoordinate(columnModel.getEndPosition())); 14320 pathElement.getColumns().add(columnElement); 14321 } 14322 14323 TableRelationRows relationRows = pathModel.getRelationRows(); 14324 if (relationRows.hasRelation()) { 14325 column relationRowsElement = new column(); 14326 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14327 relationRowsElement.setName(relationRows.getName()); 14328 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14329 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14330 + convertCoordinate(relationRows.getEndPosition())); 14331 } 14332 relationRowsElement.setSource("system"); 14333 pathElement.getColumns().add(relationRowsElement); 14334 } 14335 } 14336 14337 private void appendVariableModel(dataflow dataflow, Table variableModel) { 14338 table variableElement = new table(); 14339 variableElement.setId(String.valueOf(variableModel.getId())); 14340 if (!SQLUtil.isEmpty(variableModel.getDatabase())) { 14341 variableElement.setDatabase(variableModel.getDatabase()); 14342 } 14343 if (!SQLUtil.isEmpty(variableModel.getSchema())) { 14344 variableElement.setSchema(variableModel.getSchema()); 14345 } 14346 variableElement.setServer(variableModel.getServer()); 14347 variableElement.setName(variableModel.getName()); 14348 variableElement.setType("variable"); 14349 variableElement.setParent(variableModel.getParent()); 14350 if (variableModel.getSubType() != null) { 14351 variableElement.setSubType(variableModel.getSubType().name()); 14352 } 14353 14354 if (variableModel.getStartPosition() != null && variableModel.getEndPosition() != null) { 14355 variableElement.setCoordinate(convertCoordinate(variableModel.getStartPosition()) + "," 14356 + convertCoordinate(variableModel.getEndPosition())); 14357 } 14358 dataflow.getVariables().add(variableElement); 14359 14360 List<TableColumn> columns = variableModel.getColumns(); 14361 14362 if (containStarColumn(columns)) { 14363 for (TableColumn column : columns) { 14364 if (column.getName().endsWith("*")) { 14365 for (TableColumn starElement : columns) { 14366 if (starElement == column) { 14367 continue; 14368 } 14369 TObjectName columnObject = starElement.getColumnObject(); 14370 column.bindStarLinkColumn(columnObject); 14371 } 14372// column.setShowStar(false); 14373 } 14374 } 14375 } 14376 14377 for (int j = 0; j < columns.size(); j++) { 14378 TableColumn columnModel = columns.get(j); 14379 if (columnModel.hasStarLinkColumn()) { 14380 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 14381 for (int k = 0; k < starLinkColumnList.size(); k++) { 14382 column columnElement = new column(); 14383 columnElement.setId(columnModel.getId() + "_" + k); 14384 String columnName = starLinkColumnList.get(k); 14385 if (containStarColumn(columns, columnName)) { 14386 continue; 14387 } 14388 columnElement.setName(columnName); 14389 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14390 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14391 + convertCoordinate(columnModel.getEndPosition())); 14392 } 14393 variableElement.getColumns().add(columnElement); 14394 } 14395 14396 if (columnModel.isShowStar()) { 14397 column columnElement = new column(); 14398 columnElement.setId(String.valueOf(columnModel.getId())); 14399 columnElement.setName(columnModel.getName()); 14400 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14401 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14402 + convertCoordinate(columnModel.getEndPosition())); 14403 } 14404 variableElement.getColumns().add(columnElement); 14405 } 14406 14407 } else { 14408 column columnElement = new column(); 14409 columnElement.setId(String.valueOf(columnModel.getId())); 14410 columnElement.setName(columnModel.getName()); 14411 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14412 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14413 + convertCoordinate(columnModel.getEndPosition())); 14414 } 14415 variableElement.getColumns().add(columnElement); 14416 } 14417 } 14418 14419 TableRelationRows relationRows = variableModel.getRelationRows(); 14420 if (relationRows.hasRelation()) { 14421 column relationRowsElement = new column(); 14422 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14423 relationRowsElement.setName(relationRows.getName()); 14424 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14425 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14426 + convertCoordinate(relationRows.getEndPosition())); 14427 } 14428 relationRowsElement.setSource("system"); 14429 variableElement.getColumns().add(relationRowsElement); 14430 } 14431 } 14432 14433 private void appendCursorModel(dataflow dataflow, Table cursorModel) { 14434 table cursorElement = new table(); 14435 cursorElement.setId(String.valueOf(cursorModel.getId())); 14436 if (!SQLUtil.isEmpty(cursorModel.getDatabase())) { 14437 cursorElement.setDatabase(cursorModel.getDatabase()); 14438 } 14439 if (!SQLUtil.isEmpty(cursorModel.getSchema())) { 14440 cursorElement.setSchema(cursorModel.getSchema()); 14441 } 14442 cursorElement.setServer(cursorModel.getServer()); 14443 cursorElement.setName(cursorModel.getName()); 14444 cursorElement.setType("variable"); 14445 if (cursorElement.getSubType() != null) { 14446 cursorElement.setSubType(cursorModel.getSubType().name()); 14447 } 14448 14449 if (cursorModel.getStartPosition() != null && cursorModel.getEndPosition() != null) { 14450 cursorElement.setCoordinate(convertCoordinate(cursorModel.getStartPosition()) + "," 14451 + convertCoordinate(cursorModel.getEndPosition())); 14452 } 14453 dataflow.getVariables().add(cursorElement); 14454 14455 List<TableColumn> columns = cursorModel.getColumns(); 14456 14457 if (containStarColumn(columns)) { 14458 for (TableColumn column : columns) { 14459 if (column.getName().endsWith("*")) { 14460 for (TableColumn starElement : columns) { 14461 if (starElement == column) { 14462 continue; 14463 } 14464 TObjectName columnObject = starElement.getColumnObject(); 14465 column.bindStarLinkColumn(columnObject); 14466 } 14467 column.setShowStar(false); 14468 } 14469 } 14470 } 14471 14472 for (int j = 0; j < columns.size(); j++) { 14473 TableColumn columnModel = (TableColumn) columns.get(j); 14474 if (columnModel.hasStarLinkColumn()) { 14475 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 14476 for (int k = 0; k < starLinkColumnList.size(); k++) { 14477 column columnElement = new column(); 14478 columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k); 14479 String columnName = starLinkColumnList.get(k); 14480 if (containStarColumn(columns, columnName)) { 14481 continue; 14482 } 14483 columnElement.setName(columnName); 14484 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14485 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14486 + convertCoordinate(columnModel.getEndPosition())); 14487 } 14488 cursorElement.getColumns().add(columnElement); 14489 } 14490 14491 if (columnModel.isShowStar()) { 14492 column columnElement = new column(); 14493 columnElement.setId(String.valueOf(columnModel.getId())); 14494 columnElement.setName(columnModel.getName()); 14495 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14496 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14497 + convertCoordinate(columnModel.getEndPosition())); 14498 } 14499 cursorElement.getColumns().add(columnElement); 14500 } 14501 14502 } else { 14503 column columnElement = new column(); 14504 columnElement.setId(String.valueOf(columnModel.getId())); 14505 columnElement.setName(columnModel.getName()); 14506 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14507 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14508 + convertCoordinate(columnModel.getEndPosition())); 14509 } 14510 cursorElement.getColumns().add(columnElement); 14511 } 14512 } 14513 14514 TableRelationRows relationRows = cursorModel.getRelationRows(); 14515 if (relationRows.hasRelation()) { 14516 column relationRowsElement = new column(); 14517 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14518 relationRowsElement.setName(relationRows.getName()); 14519 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14520 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14521 + convertCoordinate(relationRows.getEndPosition())); 14522 } 14523 relationRowsElement.setSource("system"); 14524 cursorElement.getColumns().add(relationRowsElement); 14525 } 14526 } 14527 14528 private void appendErrors(dataflow dataflow) { 14529 List<ErrorInfo> errorInfos = this.getErrorMessages(); 14530 if (metadataErrors != null) { 14531 for (int i = 0; i < metadataErrors.size(); i++) { 14532 errorInfos.add(i, metadataErrors.get(i)); 14533 } 14534 } 14535 14536 for (int i = 0; i < errorInfos.size(); ++i) { 14537 ErrorInfo errorInfo = errorInfos.get(i); 14538 error error = new error(); 14539 if (!SQLUtil.isEmpty(errorInfo.getErrorMessage())) { 14540 error.setErrorMessage(errorInfo.getErrorMessage()); 14541 } 14542 if (!SQLUtil.isEmpty(errorInfo.getErrorType())) { 14543 error.setErrorType(errorInfo.getErrorType()); 14544 } 14545 if (errorInfo.getStartPosition() != null && errorInfo.getEndPosition() != null) { 14546 error.setCoordinate(convertCoordinate(errorInfo.getStartPosition()) + "," 14547 + convertCoordinate(errorInfo.getEndPosition())); 14548 } 14549 if (!SQLUtil.isEmpty(errorInfo.getFileName())) { 14550 error.setFile(errorInfo.getFileName()); 14551 } 14552 if (errorInfo.getOriginStartPosition() != null && errorInfo.getOriginEndPosition() != null) { 14553 error.setOriginCoordinate(errorInfo.getOriginStartPosition() + "," + errorInfo.getOriginEndPosition()); 14554 } 14555 dataflow.getErrors().add(error); 14556 } 14557 } 14558 14559 private void appendOraclePackages(dataflow dataflow) { 14560 List<OraclePackage> packages = this.modelManager.getOraclePackageModels(); 14561 14562 for (int i = 0; i < packages.size(); ++i) { 14563 OraclePackage model = packages.get(i); 14564 oraclePackage oraclePackage = new oraclePackage(); 14565 oraclePackage.setId(String.valueOf(model.getId())); 14566 if (!SQLUtil.isEmpty(model.getDatabase())) { 14567 oraclePackage.setDatabase(model.getDatabase()); 14568 } 14569 if (!SQLUtil.isEmpty(model.getSchema())) { 14570 oraclePackage.setSchema(model.getSchema()); 14571 } 14572 oraclePackage.setServer(model.getServer()); 14573 oraclePackage.setName(model.getName()); 14574 if (model.getType() != null) { 14575 oraclePackage.setType(model.getType().name().replace("sst", "")); 14576 } 14577 if (model.getStartPosition() != null && model.getEndPosition() != null) { 14578 oraclePackage.setCoordinate( 14579 convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition())); 14580 } 14581 14582 dataflow.getPackages().add(oraclePackage); 14583 14584 List<Argument> arguments = model.getArguments(); 14585 14586 for (int j = 0; j < arguments.size(); ++j) { 14587 Argument argumentModel = (Argument) arguments.get(j); 14588 argument argumentElement = new argument(); 14589 argumentElement.setId(String.valueOf(argumentModel.getId())); 14590 argumentElement.setName(argumentModel.getName()); 14591 if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) { 14592 argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + "," 14593 + convertCoordinate(argumentModel.getEndPosition())); 14594 } 14595 14596 argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName()); 14597 argumentElement.setInout(argumentModel.getMode().name()); 14598 oraclePackage.getArguments().add(argumentElement); 14599 } 14600 14601 for (int j = 0; j < model.getProcedures().size(); j++) { 14602 Procedure procedureModel = model.getProcedures().get(j); 14603 procedure procedure = new procedure(); 14604 procedure.setId(String.valueOf(procedureModel.getId())); 14605 if (!SQLUtil.isEmpty(procedureModel.getDatabase())) { 14606 procedure.setDatabase(procedureModel.getDatabase()); 14607 } 14608 if (!SQLUtil.isEmpty(procedureModel.getSchema())) { 14609 procedure.setSchema(procedureModel.getSchema()); 14610 } 14611 procedure.setServer(procedureModel.getServer()); 14612 procedure.setName(procedureModel.getName()); 14613 if (procedureModel.getType() != null) { 14614 procedure.setType(procedureModel.getType().name().replace("sst", "")); 14615 } 14616 if (procedureModel.getStartPosition() != null && procedureModel.getEndPosition() != null) { 14617 procedure.setCoordinate(convertCoordinate(procedureModel.getStartPosition()) + "," 14618 + convertCoordinate(procedureModel.getEndPosition())); 14619 } 14620 14621 oraclePackage.getProcedures().add(procedure); 14622 14623 List<Argument> procedureArguments = procedureModel.getArguments(); 14624 14625 for (int k = 0; k < procedureArguments.size(); ++k) { 14626 Argument argumentModel = (Argument) procedureArguments.get(k); 14627 argument argumentElement = new argument(); 14628 argumentElement.setId(String.valueOf(argumentModel.getId())); 14629 argumentElement.setName(argumentModel.getName()); 14630 if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) { 14631 argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + "," 14632 + convertCoordinate(argumentModel.getEndPosition())); 14633 } 14634 14635 argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName()); 14636 argumentElement.setInout(argumentModel.getMode().name()); 14637 procedure.getArguments().add(argumentElement); 14638 } 14639 } 14640 } 14641 } 14642 14643 private void appendProcedures(dataflow dataflow) { 14644 List<Procedure> procedures = this.modelManager.getProcedureModels(); 14645 14646 for (int i = 0; i < procedures.size(); ++i) { 14647 Procedure model = procedures.get(i); 14648 if (model.getParentPackage() != null) { 14649 continue; 14650 } 14651 procedure procedure = new procedure(); 14652 procedure.setId(String.valueOf(model.getId())); 14653 if (!SQLUtil.isEmpty(model.getDatabase())) { 14654 procedure.setDatabase(model.getDatabase()); 14655 } 14656 if (!SQLUtil.isEmpty(model.getSchema())) { 14657 procedure.setSchema(model.getSchema()); 14658 } 14659 procedure.setServer(model.getServer()); 14660 procedure.setName(model.getName()); 14661 if (model.getType() != null) { 14662 procedure.setType(model.getType().name().replace("sst", "")); 14663 } 14664 if (model.getStartPosition() != null && model.getEndPosition() != null) { 14665 procedure.setCoordinate( 14666 convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition())); 14667 } 14668 14669 dataflow.getProcedures().add(procedure); 14670 14671 List<Argument> arguments = model.getArguments(); 14672 14673 for (int j = 0; j < arguments.size(); ++j) { 14674 Argument argumentModel = (Argument) arguments.get(j); 14675 argument argumentElement = new argument(); 14676 argumentElement.setId(String.valueOf(argumentModel.getId())); 14677 argumentElement.setName(argumentModel.getName()); 14678 if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) { 14679 argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + "," 14680 + convertCoordinate(argumentModel.getEndPosition())); 14681 } 14682 14683 argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName()); 14684 argumentElement.setInout(argumentModel.getMode().name()); 14685 procedure.getArguments().add(argumentElement); 14686 } 14687 } 14688 } 14689 14690 private void appendProcesses(dataflow dataflow) { 14691 List<Process> processes = this.modelManager.getProcessModels(); 14692 14693 for (int i = 0; i < processes.size(); ++i) { 14694 Process model = processes.get(i); 14695 process process = new process(); 14696 process.setId(String.valueOf(model.getId())); 14697 if (!SQLUtil.isEmpty(model.getDatabase())) { 14698 process.setDatabase(model.getDatabase()); 14699 } 14700 if (!SQLUtil.isEmpty(model.getSchema())) { 14701 process.setSchema(model.getSchema()); 14702 } 14703 process.setServer(model.getServer()); 14704 process.setName(getProcessName(model)); 14705 if (!SQLUtil.isEmpty(model.getProcedureName())) { 14706 process.setProcedureName(model.getProcedureName()); 14707 } 14708 if (model.getProcedureId() != null) { 14709 process.setProcedureId(String.valueOf(model.getProcedureId())); 14710 } 14711 if (!SQLUtil.isEmpty(model.getQueryHashId())) { 14712 process.setQueryHashId(model.getQueryHashId()); 14713 } 14714 if (model.getGspObject() != null) { 14715 process.setType(model.getGspObject().sqlstatementtype.name()); 14716 } 14717 if (model.getStartPosition() != null && model.getEndPosition() != null) { 14718 process.setCoordinate( 14719 convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition())); 14720 } 14721 if (model.getTransforms() != null && !model.getTransforms().isEmpty()) { 14722 for (Transform transformItem : model.getTransforms()) { 14723 process.addTransform(transformItem); 14724 } 14725 } 14726 dataflow.getProcesses().add(process); 14727 } 14728 } 14729 14730 private void appendTables(dataflow dataflow) { 14731 List<TTable> tables = modelManager.getBaseTables(); 14732 Map<String, table> tableMap = new HashMap<String, table>(); 14733 Set<Long> tableModelIds = new HashSet<Long>(); 14734 for (int i = 0; i < tables.size(); i++) { 14735 Object model = modelManager.getModel(tables.get(i)); 14736 if (model instanceof Table) { 14737 Table tableModel = (Table) model; 14738 if(tableModelIds.contains(tableModel.getId())) { 14739 continue; 14740 } 14741 else { 14742 tableModelIds.add(tableModel.getId()); 14743 } 14744 if (tableModel.isView()) { 14745 continue; 14746 } 14747 if (tableModel.isStage()) { 14748 appendStageModel(dataflow, tableModel); 14749 continue; 14750 } 14751 if (tableModel.isSequence()) { 14752 appendSequenceModel(dataflow, tableModel); 14753 continue; 14754 } 14755 if (tableModel.isDataSource()) { 14756 appendDataSourceModel(dataflow, tableModel); 14757 continue; 14758 } 14759 if (tableModel.isDatabase()) { 14760 appendDatabaseModel(dataflow, tableModel); 14761 continue; 14762 } 14763 if (tableModel.isSchema()) { 14764 appendSchemaModel(dataflow, tableModel); 14765 continue; 14766 } 14767 if (tableModel.isStream()) { 14768 appendStreamModel(dataflow, tableModel); 14769 continue; 14770 } 14771 if (tableModel.isPath()) { 14772 appendPathModel(dataflow, tableModel); 14773 continue; 14774 } 14775 if (tableModel.isVariable() && !tableModel.isCursor()) { 14776 appendVariableModel(dataflow, tableModel); 14777 continue; 14778 } 14779 if (tableModel.isCursor()) { 14780 appendCursorModel(dataflow, tableModel); 14781 continue; 14782 } 14783 if (tableModel.isConstant()) { 14784 appendConstantModel(dataflow, tableModel); 14785 continue; 14786 } 14787 if (!tableIds.contains(tableModel.getId())) { 14788 appendTableModel(dataflow, tableModel, tableMap); 14789 tableIds.add(tableModel.getId()); 14790 } 14791 } else if (model instanceof QueryTable) { 14792 QueryTable queryTable = (QueryTable) model; 14793 if (!tableIds.contains(queryTable.getId())) { 14794 appendResultSet(dataflow, queryTable); 14795 tableIds.add(queryTable.getId()); 14796 } 14797 } 14798 } 14799 14800 List<Table> tableNames = modelManager.getTablesByName(); 14801 tableNames.addAll(modelManager.getDropTables()); 14802 14803 for (int i = 0; i < tableNames.size(); i++) { 14804 Table tableModel = tableNames.get(i); 14805 if(tableModelIds.contains(tableModel.getId())) { 14806 continue; 14807 } 14808 else { 14809 tableModelIds.add(tableModel.getId()); 14810 } 14811 if (tableModel.isView()) { 14812 continue; 14813 } 14814 if (tableModel.isDatabase()) { 14815 appendDatabaseModel(dataflow, tableModel); 14816 continue; 14817 } 14818 if (tableModel.isSchema()) { 14819 appendSchemaModel(dataflow, tableModel); 14820 continue; 14821 } 14822 if (tableModel.isStage()) { 14823 appendStageModel(dataflow, tableModel); 14824 continue; 14825 } 14826 if (tableModel.isSequence()) { 14827 appendSequenceModel(dataflow, tableModel); 14828 continue; 14829 } 14830 if (tableModel.isDataSource()) { 14831 appendDataSourceModel(dataflow, tableModel); 14832 continue; 14833 } 14834 if (tableModel.isStream()) { 14835 appendStreamModel(dataflow, tableModel); 14836 continue; 14837 } 14838 if (tableModel.isPath()) { 14839 appendPathModel(dataflow, tableModel); 14840 continue; 14841 } 14842 if (tableModel.isVariable()) { 14843 appendVariableModel(dataflow, tableModel); 14844 continue; 14845 } 14846 if (tableModel.isCursor()) { 14847 appendCursorModel(dataflow, tableModel); 14848 continue; 14849 } 14850 if (tableModel.isConstant()) { 14851 appendConstantModel(dataflow, tableModel); 14852 continue; 14853 } 14854 if (!tableIds.contains(tableModel.getId())) { 14855 appendTableModel(dataflow, tableModel, tableMap); 14856 tableIds.add(tableModel.getId()); 14857 } 14858 } 14859 } 14860 14861 private void appendConstantModel(dataflow dataflow, Table tableModel) { 14862 table constantElement = new table(); 14863 constantElement.setId(String.valueOf(tableModel.getId())); 14864 if (!SQLUtil.isEmpty(tableModel.getDatabase())) { 14865 constantElement.setDatabase(tableModel.getDatabase()); 14866 } 14867 if (!SQLUtil.isEmpty(tableModel.getSchema())) { 14868 constantElement.setSchema(tableModel.getSchema()); 14869 } 14870 constantElement.setServer(tableModel.getServer()); 14871 constantElement.setName(getConstantName(tableModel)); 14872 constantElement.setType("constantTable"); 14873 14874 if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) { 14875 constantElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + "," 14876 + convertCoordinate(tableModel.getEndPosition())); 14877 } 14878 dataflow.getTables().add(constantElement); 14879 14880 List<TableColumn> columns = tableModel.getColumns(); 14881 for (int j = 0; j < columns.size(); j++) { 14882 TableColumn columnModel = (TableColumn) columns.get(j); 14883 column columnElement = new column(); 14884 columnElement.setId(String.valueOf(columnModel.getId())); 14885 columnElement.setName(columnModel.getName()); 14886 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14887 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14888 + convertCoordinate(columnModel.getEndPosition())); 14889 } 14890 constantElement.getColumns().add(columnElement); 14891 } 14892 } 14893 14894 private void appendTableModel(dataflow dataflow, Table tableModel, Map<String, table> tableMap) { 14895 if(tableModel.getSubType() == SubType.unnest) {} 14896 table tableElement = new table(); 14897 tableElement.setId(String.valueOf(tableModel.getId())); 14898 if (!SQLUtil.isEmpty(tableModel.getDatabase())) { 14899 tableElement.setDatabase(tableModel.getDatabase()); 14900 } 14901 if (!SQLUtil.isEmpty(tableModel.getSchema())) { 14902 tableElement.setSchema(tableModel.getSchema()); 14903 } 14904 tableElement.setServer(tableModel.getServer()); 14905 tableElement.setName(tableModel.getName()); 14906 tableElement.setDisplayName(tableModel.getDisplayName()); 14907 tableElement.setStarStmt(tableModel.getStarStmt()); 14908 if(tableModel.isFromDDL()) { 14909 tableElement.setFromDDL(String.valueOf(tableModel.isFromDDL())); 14910 } 14911 14912 if (tableModel.isPseudo()) { 14913 tableElement.setType("pseudoTable"); 14914 } else { 14915 tableElement.setType("table"); 14916 } 14917 14918 if (tableModel.getSubType() != null) { 14919 if (tableModel.getSubType() == SubType.unnest) { 14920 tableElement.setType(SubType.unnest.name()); 14921 } 14922 else { 14923 tableElement.setSubType(tableModel.getSubType().name()); 14924 } 14925 } 14926 if (tableModel.getParent() != null) { 14927 tableElement.setParent(tableModel.getParent()); 14928 } 14929 if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) { 14930 tableElement.setAlias(tableModel.getAlias()); 14931 } 14932 if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) { 14933 if(option.isTraceTablePosition()){ 14934 for (Pair<Pair3<Long, Long, String>, Pair3<Long, Long, String>> position:tableModel.getPositions()){ 14935 tableElement.appendCoordinate(convertCoordinate(position.first)+","+convertCoordinate(position.second)); 14936 } 14937 } 14938 else { 14939 tableElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + "," 14940 + convertCoordinate(tableModel.getEndPosition())); 14941 } 14942 } 14943 if (tableModel.getProcesses() != null) { 14944 List<String> processIds = new ArrayList<String>(); 14945 for (Process process : tableModel.getProcesses()) { 14946 processIds.add(String.valueOf(process.getId())); 14947 } 14948 tableElement.setProcessIds(processIds); 14949 } 14950 14951 table oldTableElement = null; 14952 String tableFullName = DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getQualifiedTableName(tableElement)); 14953 14954 if(tableMap.containsKey(tableFullName)) { 14955 oldTableElement = tableMap.get(tableFullName); 14956 } 14957 else { 14958 tableMap.put(tableFullName, tableElement); 14959 } 14960 14961 if (tableModel.getSubType() == SubType.unnest) { 14962 dataflow.getResultsets().add(tableElement); 14963 } else { 14964 dataflow.getTables().add(tableElement); 14965 } 14966 14967 List<TableColumn> columns = tableModel.getColumns(); 14968 14969 if (containStarColumn(columns)) { 14970 for (TableColumn column : columns) { 14971 if (column.getName().endsWith("*")) { 14972 for (TableColumn starElement : columns) { 14973 if (starElement == column) { 14974 continue; 14975 } 14976 if (starElement.isNotBindStarLinkColumn()) { 14977 continue; 14978 } 14979 TObjectName columnObject = starElement.getColumnObject(); 14980 column.bindStarLinkColumn(columnObject); 14981 } 14982 if (tableModel.isCreateTable() && column.isExpandStar()) { 14983 column.setShowStar(false); 14984 } 14985 } 14986 } 14987 } 14988 14989 for (int j = 0; j < columns.size(); j++) { 14990 TableColumn columnModel = columns.get(j); 14991 14992 if(oldTableElement != null){ 14993 if(!CollectionUtil.isEmpty(oldTableElement.getColumns())){ 14994 for(column oldColumnElement: oldTableElement.getColumns()){ 14995 if(oldColumnElement.getName().equalsIgnoreCase(columnModel.getName())){ 14996 if(columnModel.getDataType() == null && oldColumnElement.getDataType() != null){ 14997 columnModel.setDataType(oldColumnElement.getDataType()); 14998 } 14999 if(columnModel.getPrimaryKey() == null && oldColumnElement.isPrimaryKey() != null){ 15000 columnModel.setPrimaryKey(oldColumnElement.isPrimaryKey()); 15001 } 15002 if(columnModel.getIndexKey() == null && oldColumnElement.isIndexKey() != null){ 15003 columnModel.setIndexKey(oldColumnElement.isIndexKey()); 15004 } 15005 if(columnModel.getUnqiueKey() == null && oldColumnElement.isUnqiueKey() != null){ 15006 columnModel.setUnqiueKey(oldColumnElement.isUnqiueKey()); 15007 } 15008 if(columnModel.getForeignKey() == null && oldColumnElement.isForeignKey() != null){ 15009 columnModel.setForeignKey(oldColumnElement.isForeignKey()); 15010 } 15011 15012 if(oldColumnElement.getDataType() == null && columnModel.getDataType() != null){ 15013 oldColumnElement.setDataType(columnModel.getDataType()); 15014 } 15015 if(oldColumnElement.isPrimaryKey() == null && columnModel.getPrimaryKey() != null){ 15016 oldColumnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15017 } 15018 if(oldColumnElement.isIndexKey() == null && columnModel.getIndexKey() != null){ 15019 oldColumnElement.setIndexKey(columnModel.getIndexKey()); 15020 } 15021 if(oldColumnElement.isUnqiueKey() == null && columnModel.getUnqiueKey() != null){ 15022 oldColumnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15023 } 15024 if(oldColumnElement.isForeignKey() == null && columnModel.getForeignKey() != null){ 15025 oldColumnElement.setForeignKey(columnModel.getForeignKey()); 15026 } 15027 break; 15028 } 15029 } 15030 } 15031 15032 } 15033 15034 if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn() && !columnModel.isVariant()) { 15035 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 15036 for (int k = 0; k < starLinkColumnList.size(); k++) { 15037 column columnElement = new column(); 15038 columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k); 15039 String columnName = starLinkColumnList.get(k); 15040 if (containStarColumn(columns, columnName)) { 15041 continue; 15042 } 15043 columnElement.setName(columnName); 15044 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15045 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15046 + convertCoordinate(columnModel.getEndPosition())); 15047 } 15048 if (columnModel.getForeignKey()) { 15049 columnElement.setForeignKey(columnModel.getForeignKey()); 15050 } 15051 if (columnModel.getIndexKey()) { 15052 columnElement.setIndexKey(columnModel.getIndexKey()); 15053 } 15054 if (columnModel.getPrimaryKey()) { 15055 columnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15056 } 15057 if (columnModel.getUnqiueKey()) { 15058 columnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15059 } 15060 if (columnModel.getDataType() != null) { 15061 columnElement.setDataType(columnModel.getDataType()); 15062 } 15063 tableElement.getColumns().add(columnElement); 15064 } 15065 if (columnModel.isShowStar()) { 15066 column columnElement = new column(); 15067 columnElement.setId(String.valueOf(columnModel.getId())); 15068 columnElement.setName(columnModel.getName()); 15069 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15070 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15071 + convertCoordinate(columnModel.getEndPosition())); 15072 } 15073 if (columnModel.getForeignKey()) { 15074 columnElement.setForeignKey(columnModel.getForeignKey()); 15075 } 15076 if (columnModel.getIndexKey()) { 15077 columnElement.setIndexKey(columnModel.getIndexKey()); 15078 } 15079 if (columnModel.getPrimaryKey()) { 15080 columnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15081 } 15082 if (columnModel.getUnqiueKey()) { 15083 columnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15084 } 15085 if (columnModel.getDataType() != null) { 15086 columnElement.setDataType(columnModel.getDataType()); 15087 } 15088 tableElement.getColumns().add(columnElement); 15089 } 15090 } else { 15091 column columnElement = new column(); 15092 columnElement.setId(String.valueOf(columnModel.getId())); 15093 columnElement.setName(columnModel.getName()); 15094 columnElement.setDisplayName(columnModel.getDisplayName()); 15095 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15096 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15097 + convertCoordinate(columnModel.getEndPosition())); 15098 } 15099 if (columnModel.isPseduo()) { 15100 columnElement.setSource("system"); 15101 } 15102 if (columnModel.getForeignKey()) { 15103 columnElement.setForeignKey(columnModel.getForeignKey()); 15104 } 15105 if (columnModel.getIndexKey()) { 15106 columnElement.setIndexKey(columnModel.getIndexKey()); 15107 } 15108 if (columnModel.getPrimaryKey()) { 15109 columnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15110 } 15111 if (columnModel.getUnqiueKey()) { 15112 columnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15113 } 15114 if (columnModel.getDataType() != null) { 15115 columnElement.setDataType(columnModel.getDataType()); 15116 } 15117 tableElement.getColumns().add(columnElement); 15118 } 15119 } 15120 15121 TableRelationRows relationRows = tableModel.getRelationRows(); 15122 if (relationRows.hasRelation()) { 15123 column relationRowsElement = new column(); 15124 relationRowsElement.setId(String.valueOf(relationRows.getId())); 15125 relationRowsElement.setName(relationRows.getName()); 15126 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 15127 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 15128 + convertCoordinate(relationRows.getEndPosition())); 15129 } 15130 relationRowsElement.setSource("system"); 15131 tableElement.getColumns().add(relationRowsElement); 15132 } 15133 } 15134 15135 private boolean containStarColumn(List<TableColumn> columns, String qualifiedColumnName) { 15136 for (TableColumn tableColumn : columns) { 15137 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) { 15138 return true; 15139 } 15140 } 15141 return false; 15142 } 15143 15144 private TableColumn searchTableColumn(List<TableColumn> columns, String qualifiedColumnName) { 15145 for (TableColumn tableColumn : columns) { 15146 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) { 15147 return tableColumn; 15148 } 15149 } 15150 return null; 15151 } 15152 15153 private boolean containStarColumn(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) { 15154 for (RelationshipElement element : elements) { 15155 if (element.getElement() instanceof TableColumn) { 15156 if (DlineageUtil.getIdentifierNormalColumnName(((TableColumn) element.getElement()).getName()) 15157 .equals(qualifiedColumnName)) { 15158 return true; 15159 } 15160 } else if (element.getElement() instanceof ResultColumn) { 15161 if (DlineageUtil.getIdentifierNormalColumnName(((ResultColumn) element.getElement()).getName()) 15162 .equals(qualifiedColumnName)) { 15163 return true; 15164 } 15165 } 15166 } 15167 return false; 15168 } 15169 15170 /** 15171 * Returns true if there is a non-star source element matching the column name 15172 * whose parent (table/resultset) does NOT also contribute a star source in 15173 * the same relationship. This identifies "definitive" explicit sources like 15174 * subquery columns (e.g., "coalesce(...) as col_a") vs incidental references 15175 * (e.g., "aTab.id" where aTab.* is also a source). 15176 */ 15177 private boolean hasDefinitiveNonStarSource(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) { 15178 // First, collect parent IDs of all star (*) sources 15179 Set<Long> starSourceParentIds = new HashSet<Long>(); 15180 for (RelationshipElement<?> element : elements) { 15181 if (element.getElement() instanceof TableColumn) { 15182 TableColumn tc = (TableColumn) element.getElement(); 15183 if ("*".equals(tc.getName()) && tc.getTable() != null) { 15184 starSourceParentIds.add(tc.getTable().getId()); 15185 } 15186 } else if (element.getElement() instanceof ResultColumn) { 15187 ResultColumn rc = (ResultColumn) element.getElement(); 15188 if ("*".equals(rc.getName()) && rc.getResultSet() != null) { 15189 starSourceParentIds.add(rc.getResultSet().getId()); 15190 } 15191 } 15192 } 15193 15194 // Then check if any non-star source matching the column name has a parent 15195 // that does NOT also have a star source 15196 for (RelationshipElement<?> element : elements) { 15197 if (element.getElement() instanceof TableColumn) { 15198 TableColumn tc = (TableColumn) element.getElement(); 15199 if (!"*".equals(tc.getName()) 15200 && DlineageUtil.getIdentifierNormalColumnName(tc.getName()).equals(qualifiedColumnName)) { 15201 if (tc.getTable() != null && !starSourceParentIds.contains(tc.getTable().getId())) { 15202 return true; 15203 } 15204 } 15205 } else if (element.getElement() instanceof ResultColumn) { 15206 ResultColumn rc = (ResultColumn) element.getElement(); 15207 if (!"*".equals(rc.getName()) 15208 && DlineageUtil.getIdentifierNormalColumnName(rc.getName()).equals(qualifiedColumnName)) { 15209 if (rc.getResultSet() != null && !starSourceParentIds.contains(rc.getResultSet().getId())) { 15210 return true; 15211 } 15212 } 15213 } 15214 } 15215 return false; 15216 } 15217 15218 private void analyzeSelectStmt(TSelectSqlStatement stmt) { 15219 if (!accessedSubqueries.contains(stmt)) { 15220 accessedSubqueries.add(stmt); 15221 } else { 15222 if (modelManager.getModel(stmt) != null) { 15223 return; 15224 } 15225 } 15226 15227 if (stmt.getParentStmt() == null && stmt.getIntoClause() == null && stmt.getIntoTableClause() == null) { 15228 if(option.isIgnoreTopSelect() && (option.isIgnoreRecordSet() || option.isSimpleOutput())){ 15229 if(option.getAnalyzeMode() == null || option.getAnalyzeMode() == AnalyzeMode.dataflow){ 15230 return; 15231 } 15232 } 15233 } 15234 15235 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 15236 15237 // Iteratively analyze all descendant UNION branches before processing this node. 15238 // Uses iterative post-order traversal to preserve the original left-right-self 15239 // processing order, avoiding StackOverflow with deeply nested UNION trees. 15240 { 15241 Deque<TSelectSqlStatement> stack1 = new ArrayDeque<>(); 15242 List<TSelectSqlStatement> postOrder = new ArrayList<>(); 15243 stack1.push(stmt); 15244 while (!stack1.isEmpty()) { 15245 TSelectSqlStatement node = stack1.pop(); 15246 postOrder.add(node); 15247 if (node.getSetOperatorType() != ESetOperatorType.none) { 15248 // Push left first, then right, so that after reversal left comes first 15249 if (node.getLeftStmt() != null) stack1.push(node.getLeftStmt()); 15250 if (node.getRightStmt() != null) stack1.push(node.getRightStmt()); 15251 } 15252 } 15253 Collections.reverse(postOrder); 15254 // Process all descendants in post-order, skip stmt itself (processed below) 15255 for (int pi = 0; pi < postOrder.size() - 1; pi++) { 15256 TSelectSqlStatement node = postOrder.get(pi); 15257 if (!accessedStatements.contains(node)) { 15258 accessedStatements.add(node); 15259 analyzeSelectStmt(node); 15260 } 15261 } 15262 } 15263 15264 stmtStack.push(stmt); 15265 SelectSetResultSet resultSet = modelFactory.createSelectSetResultSet(stmt); 15266 15267 ResultSet leftResultSetModel = (ResultSet) modelManager.getModel(stmt.getLeftStmt()); 15268 if (leftResultSetModel != null && leftResultSetModel != resultSet 15269 && !leftResultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 15270 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 15271 impactRelation.setEffectType(EffectType.select); 15272 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15273 leftResultSetModel.getRelationRows())); 15274 impactRelation.setTarget( 15275 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 15276 } 15277 15278 ResultSet rightResultSetModel = (ResultSet) modelManager.getModel(stmt.getRightStmt()); 15279 if (rightResultSetModel != null && rightResultSetModel != resultSet 15280 && !rightResultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 15281 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 15282 impactRelation.setEffectType(EffectType.select); 15283 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15284 rightResultSetModel.getRelationRows())); 15285 impactRelation.setTarget( 15286 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 15287 } 15288 15289 if ((leftResultSetModel != null && leftResultSetModel.isDetermined()) 15290 || (rightResultSetModel != null && rightResultSetModel.isDetermined())) { 15291 resultSet.setDetermined(true); 15292 } 15293 15294 if (resultSet.getColumns() == null || resultSet.getColumns().isEmpty()) { 15295 if (getResultColumnList(stmt.getLeftStmt()) != null) { 15296 createSelectSetResultColumns(resultSet, stmt.getLeftStmt()); 15297 } else if (getResultColumnList(stmt.getRightStmt()) != null) { 15298 createSelectSetResultColumns(resultSet, stmt.getRightStmt()); 15299 } 15300 } 15301 15302 List<ResultColumn> columns = resultSet.getColumns(); 15303 for (int i = 0; i < columns.size(); i++) { 15304 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 15305 relation.setEffectType(EffectType.select); 15306 relation.setTarget(new ResultColumnRelationshipElement(columns.get(i))); 15307 15308 if (!stmt.getLeftStmt().isCombinedQuery()) { 15309 ResultSet sourceResultSet = (ResultSet) modelManager 15310 .getModel(stmt.getLeftStmt().getResultColumnList()); 15311 if (sourceResultSet!=null && sourceResultSet.getColumns().size() > i) { 15312 if (columns.get(i).getName().endsWith("*")) { 15313 for (ResultColumn column : sourceResultSet.getColumns()) { 15314 relation.addSource(new ResultColumnRelationshipElement(column)); 15315 } 15316 } else { 15317 relation.addSource( 15318 new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 15319 } 15320 } 15321 } else { 15322 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getLeftStmt()); 15323 if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) { 15324 if (columns.get(i).getName().endsWith("*")) { 15325 for (ResultColumn column : sourceResultSet.getColumns()) { 15326 relation.addSource(new ResultColumnRelationshipElement(column)); 15327 } 15328 } else { 15329 relation.addSource( 15330 new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 15331 } 15332 } 15333 } 15334 15335 if (!stmt.getRightStmt().isCombinedQuery()) { 15336 ResultSet sourceResultSet = (ResultSet) modelManager 15337 .getModel(stmt.getRightStmt().getResultColumnList()); 15338 if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) { 15339 if (columns.get(i).getName().endsWith("*")) { 15340 for (ResultColumn column : sourceResultSet.getColumns()) { 15341 relation.addSource(new ResultColumnRelationshipElement(column)); 15342 } 15343 } else { 15344 relation.addSource( 15345 new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 15346 } 15347 } else if (sourceResultSet != null) { 15348 for (ResultColumn column : sourceResultSet.getColumns()) { 15349 if (column.hasStarLinkColumn()) { 15350 relation.addSource(new ResultColumnRelationshipElement(column)); 15351 } 15352 } 15353 } 15354 } else { 15355 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getRightStmt()); 15356 if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) { 15357 relation.addSource(new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 15358 } else if (sourceResultSet != null) { 15359 for (ResultColumn column : sourceResultSet.getColumns()) { 15360 if (column.hasStarLinkColumn()) { 15361 relation.addSource(new ResultColumnRelationshipElement(column)); 15362 } 15363 } 15364 } 15365 } 15366 } 15367 15368 analyzeSelectIntoClause(stmt); 15369 15370 stmtStack.pop(); 15371 } else { 15372 15373 // handle hive stmt, issue_id I3SGZB 15374 if (stmt.getHiveBodyList() != null && stmt.getHiveBodyList().size() > 0) { 15375 stmtStack.push(stmt); 15376 hiveFromTables = stmt.tables; 15377 if (hiveFromTables != null) { 15378 for (int i = 0; i < hiveFromTables.size(); i++) { 15379 modelFactory.createTable(hiveFromTables.getTable(i)); 15380 } 15381 } 15382 for (int i = 0; i < stmt.getHiveBodyList().size(); i++) { 15383 analyzeCustomSqlStmt(stmt.getHiveBodyList().get(i)); 15384 } 15385 stmtStack.pop(); 15386 return; 15387 } 15388 15389 if (stmt.getTransformClause() != null) { 15390 analyzeHiveTransformClause(stmt, stmt.getTransformClause()); 15391 return; 15392 } 15393 15394 if (stmt.getResultColumnList() == null) { 15395 return; 15396 } 15397 15398 stmtStack.push(stmt); 15399 15400 TTableList fromTables = stmt.tables; 15401 if ((fromTables == null || fromTables.size() == 0) 15402 && (hiveFromTables != null && hiveFromTables.size() > 0)) { 15403 fromTables = hiveFromTables; 15404 } 15405 15406 for (int i = 0; i < fromTables.size(); i++) { 15407 TTable table = fromTables.getTable(i); 15408 if (table.getLateralViewList() != null && !table.getLateralViewList().isEmpty()) { 15409 analyzeTableSubquery(table); 15410 analyzeLateralView(stmt, table, table.getLateralViewList()); 15411 stmtStack.pop(); 15412 return; 15413 } 15414 if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvpresto) { 15415 analyzeTableSubquery(table); 15416 analyzePrestoUnnest(stmt, table); 15417 stmtStack.pop(); 15418 return; 15419 } 15420 if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvbigquery) { 15421 analyzeBigQueryUnnest(stmt, table); 15422 } 15423 } 15424 15425 //用来获取 pivotedTable 对应的columns 15426 TPivotedTable pivotedTable = null; 15427 if (stmt.getJoins() != null && stmt.getJoins().size() > 0) { 15428 for (TJoin join : stmt.getJoins()) { 15429 if (join.getTable() != null && join.getTable().getPivotedTable() != null) { 15430 if (isUnPivotedTable(join.getTable().getPivotedTable())) { 15431 analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable()); 15432 pivotedTable = join.getTable().getPivotedTable(); 15433 } else { 15434 analyzePivotedTable(stmt, join.getTable().getPivotedTable()); 15435 pivotedTable = join.getTable().getPivotedTable(); 15436 } 15437 } 15438 } 15439 } 15440 15441 for (int i = 0; i < fromTables.size(); i++) { 15442 TTable table = fromTables.getTable(i); 15443 // Handle TABLE(func()) which has tableType=tableExpr and funcCall=null 15444 if (table.getTableType() == ETableSource.tableExpr && table.getFuncCall() == null && pipelinedAnalyzer != null) { 15445 try { 15446 pipelinedAnalyzer.tryStitchTableExpr(table); 15447 } catch (Exception e) { 15448 // Don't let pipelined stitching failure break main flow 15449 } 15450 } 15451 15452 if (table.getFuncCall() != null || (table.getTableExpr()!=null && table.getTableExpr().getFunctionCall()!=null)) { 15453 TFunctionCall functionCall = table.getFuncCall(); 15454 if (functionCall == null) { 15455 functionCall = table.getTableExpr().getFunctionCall(); 15456 } 15457 Procedure callee = modelManager.getProcedureByName( 15458 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 15459 if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 15460 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 15461 callee = modelManager.getProcedureByName( 15462 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 15463 } 15464 15465 if(callee!=null) { 15466 if (callee.getArguments() != null) { 15467 for (int j = 0; j < callee.getArguments().size(); j++) { 15468 Argument argument = callee.getArguments().get(j); 15469 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 15470 if(variable!=null) { 15471 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 15472 Transform transform = new Transform(); 15473 transform.setType(Transform.FUNCTION); 15474 transform.setCode(functionCall); 15475 variable.getColumns().get(0).setTransform(transform); 15476 } 15477 Process process = modelFactory.createProcess(functionCall); 15478 variable.addProcess(process); 15479 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process); 15480 } 15481 } 15482 } 15483 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil 15484 .getIdentifierNormalTableName(functionCall.getFunctionName().toString())); 15485 if (functionTableModelObjs != null) { 15486 modelManager.bindModel(table, functionTableModelObjs.iterator().next()); 15487 } 15488 // Try pipelined function stitching 15489 if (pipelinedAnalyzer != null) { 15490 try { 15491 pipelinedAnalyzer.tryStitchCallSite(table, functionCall); 15492 } catch (Exception e) { 15493 // Don't let pipelined stitching failure break main flow 15494 } 15495 } 15496 continue; 15497 } else { 15498 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil 15499 .getIdentifierNormalTableName(functionCall.getFunctionName().toString())); 15500 if (functionTableModelObjs == null) { 15501// Procedure procedure = modelManager.getProcedureByName(DlineageUtil 15502// .getIdentifierNormalTableName(functionCall.getFunctionName().toString())); 15503// if (procedure != null) { 15504 createFunction(functionCall); 15505 continue; 15506// } 15507 } 15508 if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof Table) { 15509 Table functionTableModel = (Table) functionTableModelObjs.iterator().next(); 15510 if (functionTableModel.getColumns() != null) { 15511 Table functionTable = modelFactory.createTableFromCreateDDL(table, true); 15512 if (functionTable == functionTableModel) 15513 continue; 15514 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 15515 TableColumn column = modelFactory.createTableColumn(functionTable, 15516 functionTableModel.getColumns().get(j).getColumnObject(), true); 15517 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 15518 relation.setEffectType(EffectType.select); 15519 relation.setTarget(new TableColumnRelationshipElement(column)); 15520 relation.addSource( 15521 new TableColumnRelationshipElement(functionTableModel.getColumns().get(j))); 15522 } 15523 } 15524 } else if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) { 15525 ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next(); 15526 if (functionTableModel.getColumns() != null) { 15527 Table functionTable = modelFactory.createTableFromCreateDDL(table, true); 15528 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 15529 TParseTreeNode columnObj = functionTableModel.getColumns().get(j).getColumnObject(); 15530 if (columnObj instanceof TObjectName) { 15531 TableColumn column = modelFactory.createTableColumn(functionTable, 15532 (TObjectName) columnObj, true); 15533 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 15534 relation.setEffectType(EffectType.select); 15535 relation.setTarget(new TableColumnRelationshipElement(column)); 15536 relation.addSource(new ResultColumnRelationshipElement( 15537 functionTableModel.getColumns().get(j))); 15538 } else if (columnObj instanceof TResultColumn) { 15539 TableColumn column = modelFactory.createTableColumn(functionTable, 15540 (TResultColumn) columnObj); 15541 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 15542 relation.setEffectType(EffectType.select); 15543 relation.setTarget(new TableColumnRelationshipElement(column)); 15544 relation.addSource(new ResultColumnRelationshipElement( 15545 functionTableModel.getColumns().get(j))); 15546 } 15547 } 15548 } 15549 } 15550 // Try pipelined function stitching for unresolved function calls 15551 if (pipelinedAnalyzer != null) { 15552 try { 15553 pipelinedAnalyzer.tryStitchCallSite(table, functionCall); 15554 } catch (Exception e) { 15555 // Don't let pipelined stitching failure break main flow 15556 } 15557 } 15558 } 15559 } 15560 15561 if (table.getPartitionExtensionClause() != null 15562 && table.getPartitionExtensionClause().getKeyValues() != null) { 15563 TExpressionList values = table.getPartitionExtensionClause().getKeyValues(); 15564 Table tableModel = modelFactory.createTable(table); 15565 for (TExpression value : values) { 15566 if (value.getExpressionType() == EExpressionType.simple_constant_t) { 15567 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 15568 impactRelation.setEffectType(EffectType.select); 15569 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 15570 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, value.getConstantOperand()); 15571 impactRelation.addSource(new TableColumnRelationshipElement(constantColumn)); 15572 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 15573 tableModel.getRelationRows())); 15574 } 15575 } 15576 } 15577 15578 if (table.getSubquery() != null) { 15579 QueryTable queryTable = modelFactory.createQueryTable(table); 15580 TSelectSqlStatement subquery = table.getSubquery(); 15581 analyzeSelectStmt(subquery); 15582 15583 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 15584 if (resultSetModel != null && resultSetModel.isDetermined()) { 15585 queryTable.setDetermined(true); 15586 } 15587 15588 if (resultSetModel != null && resultSetModel != queryTable 15589 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 15590 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 15591 impactRelation.setEffectType(EffectType.select); 15592 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15593 resultSetModel.getRelationRows())); 15594 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15595 queryTable.getRelationRows())); 15596 } 15597 15598 if (resultSetModel != null && resultSetModel != queryTable 15599 && queryTable.getTableObject().getAliasClause() != null 15600 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 15601 for (int j = 0; j < queryTable.getColumns().size() 15602 && j < resultSetModel.getColumns().size(); j++) { 15603 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 15604 ResultColumn targetColumn = queryTable.getColumns().get(j); 15605 15606 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 15607 queryRalation.setEffectType(EffectType.select); 15608 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 15609 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 15610 } 15611 } else if (subquery.getSetOperatorType() != ESetOperatorType.none) { 15612 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 15613 .getModel(subquery); 15614 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 15615 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 15616 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 15617 sourceColumn); 15618 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 15619 targetColumn.bindStarLinkColumn(starLinkColumn); 15620 } 15621 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 15622 selectSetRalation.setEffectType(EffectType.select); 15623 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 15624 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 15625 } 15626 } 15627 } else if (table.getOutputMerge() != null) { 15628 QueryTable queryTable = modelFactory.createQueryTable(table); 15629 TMergeSqlStatement subquery = table.getOutputMerge(); 15630 analyzeMergeStmt(subquery); 15631 15632 for (TResultColumn column : subquery.getOutputClause().getSelectItemList()) { 15633 modelFactory.createResultColumn(queryTable, column); 15634 analyzeResultColumn(column, EffectType.select); 15635 } 15636 15637 ResultSet resultSetModel = (ResultSet) modelManager 15638 .getModel(subquery.getOutputClause().getSelectItemList()); 15639 15640 if (resultSetModel != null && resultSetModel != queryTable 15641 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 15642 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 15643 impactRelation.setEffectType(EffectType.select); 15644 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15645 resultSetModel.getRelationRows())); 15646 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15647 queryTable.getRelationRows())); 15648 } 15649 15650 if (resultSetModel != null && resultSetModel != queryTable 15651 && queryTable.getTableObject().getAliasClause() != null 15652 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 15653 for (int j = 0; j < queryTable.getColumns().size() 15654 && j < resultSetModel.getColumns().size(); j++) { 15655 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 15656 ResultColumn targetColumn = queryTable.getColumns().get(j); 15657 15658 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 15659 queryRalation.setEffectType(EffectType.select); 15660 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 15661 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 15662 } 15663 } 15664 } else if (table.getTableExpr() != null && table.getTableExpr().getSubQuery() != null) { 15665 QueryTable queryTable = modelFactory.createQueryTable(table); 15666 TSelectSqlStatement subquery = table.getTableExpr().getSubQuery(); 15667 analyzeSelectStmt(subquery); 15668 15669 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 15670 15671 if (resultSetModel != null && resultSetModel != queryTable 15672 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 15673 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 15674 impactRelation.setEffectType(EffectType.select); 15675 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15676 resultSetModel.getRelationRows())); 15677 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15678 queryTable.getRelationRows())); 15679 } 15680 15681 if (resultSetModel != null && resultSetModel != queryTable 15682 && queryTable.getTableObject().getAliasClause() != null) { 15683 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 15684 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 15685 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 15686 sourceColumn); 15687 15688 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 15689 queryRalation.setEffectType(EffectType.select); 15690 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 15691 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 15692 } 15693 } else if (subquery.getSetOperatorType() != ESetOperatorType.none) { 15694 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 15695 .getModel(subquery); 15696 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 15697 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 15698 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 15699 sourceColumn); 15700 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 15701 targetColumn.bindStarLinkColumn(starLinkColumn); 15702 } 15703 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 15704 selectSetRalation.setEffectType(EffectType.select); 15705 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 15706 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 15707 } 15708 } 15709 } else if (table.getCTE() != null) { 15710 QueryTable queryTable = modelFactory.createQueryTable(table); 15711 15712 TObjectNameList cteColumns = table.getCTE().getColumnList(); 15713 if (cteColumns != null) { 15714 for (int j = 0; j < cteColumns.size(); j++) { 15715 modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j)); 15716 } 15717 queryTable.setDetermined(true); 15718 } 15719 TSelectSqlStatement subquery = table.getCTE().getSubquery(); 15720 if (subquery != null && !stmtStack.contains(subquery) && subquery.getResultColumnList() != null) { 15721 analyzeSelectStmt(subquery); 15722 15723 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 15724 if (resultSetModel != null && resultSetModel != queryTable 15725 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 15726 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 15727 impactRelation.setEffectType(EffectType.select); 15728 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15729 resultSetModel.getRelationRows())); 15730 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 15731 queryTable.getRelationRows())); 15732 } 15733 15734 if (subquery.getSetOperatorType() != ESetOperatorType.none) { 15735 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 15736 .getModel(subquery); 15737 int x = 0; 15738 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 15739 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 15740 ResultColumn targetColumn = null; 15741 if (cteColumns != null) { 15742 if (queryTable.getColumns().size() <= j) { 15743 for (int k = 0; k < queryTable.getColumns().size(); k++) { 15744 if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName()) 15745 || queryTable.getColumns().get(k).getName() 15746 .equals(sourceColumn.getAlias())) { 15747 targetColumn = queryTable.getColumns().get(k); 15748 } 15749 } 15750 } else { 15751 if (x < j) { 15752 x = j; 15753 } 15754 targetColumn = queryTable.getColumns().get(x); 15755 x++; 15756 if (resultSetModel.getColumns().get(j).getName().contains("*") 15757 && x < cteColumns.size()) { 15758 j--; 15759 } 15760 } 15761 } else { 15762 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 15763 } 15764 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 15765 targetColumn.bindStarLinkColumn(starLinkColumn); 15766 } 15767 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 15768 selectSetRalation.setEffectType(EffectType.select); 15769 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 15770 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 15771 } 15772 if (!queryTable.isDetermined()) { 15773 queryTable.setDetermined(selectSetResultSetModel.isDetermined()); 15774 } 15775 } else { 15776 int x = 0; 15777 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 15778 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 15779 ResultColumn targetColumn = null; 15780 if (cteColumns != null) { 15781 if (queryTable.getColumns().size() <= j) { 15782 for (int k = 0; k < queryTable.getColumns().size(); k++) { 15783 if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName()) 15784 || queryTable.getColumns().get(k).getName() 15785 .equals(sourceColumn.getAlias())) { 15786 targetColumn = queryTable.getColumns().get(k); 15787 } 15788 } 15789 } else { 15790 if (x < j) { 15791 x = j; 15792 } 15793 targetColumn = queryTable.getColumns().get(x); 15794 x++; 15795 if (resultSetModel.getColumns().get(j).getName().contains("*") 15796 && x < cteColumns.size()) { 15797 j--; 15798 } 15799 } 15800 } else { 15801 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 15802 } 15803 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 15804 targetColumn.bindStarLinkColumn(starLinkColumn); 15805 } 15806 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 15807 selectSetRalation.setEffectType(EffectType.select); 15808 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 15809 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 15810 } 15811 if (!queryTable.isDetermined()) { 15812 queryTable.setDetermined(resultSetModel.isDetermined()); 15813 } 15814 } 15815 } else if (table.getCTE().getUpdateStmt() != null) { 15816 analyzeCustomSqlStmt(table.getCTE().getUpdateStmt()); 15817 } else if (table.getCTE().getInsertStmt() != null) { 15818 analyzeCustomSqlStmt(table.getCTE().getInsertStmt()); 15819 } else if (table.getCTE().getDeleteStmt() != null) { 15820 analyzeCustomSqlStmt(table.getCTE().getDeleteStmt()); 15821 } 15822 } else if (table.getTableType().name().startsWith("open")) { 15823 continue; 15824 } else if (table.getTableType() == ETableSource.jsonTable) { 15825 Table functionTable = modelFactory.createJsonTable(table); 15826 TJsonTable jsonTable = table.getJsonTable(); 15827 TColumnDefinitionList definitions = jsonTable.getColumnDefinitions(); 15828 if (definitions != null) { 15829 for (int j = 0; j < definitions.size(); j++) { 15830 TColumnDefinitionList nestDefinitions = definitions.getColumn(j).getNestedTableColumns(); 15831 if(nestDefinitions!=null) { 15832 for(int k=0;k<nestDefinitions.size();k++){ 15833 TableColumn column = modelFactory.createTableColumn(functionTable, 15834 nestDefinitions.getColumn(k).getColumnName(), true); 15835 if (nestDefinitions.getColumn(k).getColumnPath() != null) { 15836 column.setDisplayName( 15837 column.getName() + ":" + nestDefinitions.getColumn(k).getColumnPath()); 15838 } 15839 } 15840 } 15841 else { 15842 TableColumn column = modelFactory.createTableColumn(functionTable, 15843 definitions.getColumn(j).getColumnName(), true); 15844 if (definitions.getColumn(j).getColumnPath() != null) { 15845 column.setDisplayName( 15846 column.getName() + ":" + definitions.getColumn(j).getColumnPath()); 15847 } 15848 } 15849 } 15850 } else { 15851 TObjectName keyColumn = new TObjectName(); 15852 keyColumn.setString("key"); 15853 modelFactory.createJsonTableColumn(functionTable, keyColumn); 15854 TObjectName valueColumn = new TObjectName(); 15855 valueColumn.setString("value"); 15856 modelFactory.createJsonTableColumn(functionTable, valueColumn); 15857 TObjectName typeColumn = new TObjectName(); 15858 typeColumn.setString("type"); 15859 modelFactory.createJsonTableColumn(functionTable, typeColumn); 15860 } 15861 15862 functionTable.setCreateTable(true); 15863 functionTable.setSubType(SubType.function); 15864 modelManager.bindCreateModel(table, functionTable); 15865 15866 if (jsonTable.getJsonExpression() == null) { 15867 ErrorInfo errorInfo = new ErrorInfo(); 15868 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 15869 errorInfo.setErrorMessage("Can't handle the json table: " + jsonTable.toString()); 15870 errorInfo.setStartPosition(new Pair3<Long, Long, String>(jsonTable.getStartToken().lineNo, 15871 jsonTable.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 15872 errorInfo.setEndPosition(new Pair3<Long, Long, String>(jsonTable.getEndToken().lineNo, 15873 jsonTable.getEndToken().columnNo + jsonTable.getEndToken().getAstext().length(), 15874 ModelBindingManager.getGlobalHash())); 15875 errorInfo.fillInfo(this); 15876 errorInfos.add(errorInfo); 15877 } else { 15878 String jsonName = jsonTable.getJsonExpression().toString(); 15879 if (!jsonName.startsWith("@")) { 15880 columnsInExpr visitor = new columnsInExpr(); 15881 jsonTable.getJsonExpression().inOrderTraverse(visitor); 15882 List<TObjectName> objectNames = visitor.getObjectNames(); 15883 List<TParseTreeNode> functions = visitor.getFunctions(); 15884 List<TParseTreeNode> constants = visitor.getConstants(); 15885 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 15886 15887 for (int j = 0; j < functionTable.getColumns().size(); j++) { 15888 TableColumn tableColumn = functionTable.getColumns().get(j); 15889 if (functions != null && !functions.isEmpty()) { 15890 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 15891 } 15892 if (subquerys != null && !subquerys.isEmpty()) { 15893 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 15894 } 15895 if (objectNames != null && !objectNames.isEmpty()) { 15896 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 15897 } 15898 if (constants != null && !constants.isEmpty()) { 15899 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, 15900 functions); 15901 } 15902 } 15903 } else { 15904 TStatementList stmts = stmt.getGsqlparser().getSqlstatements(); 15905 for (int j = 0; j < stmts.size(); j++) { 15906 TCustomSqlStatement item = stmts.get(j); 15907 if (item instanceof TMssqlDeclare) { 15908 if (analyzeMssqlJsonDeclare((TMssqlDeclare) item, jsonName, functionTable)) { 15909 break; 15910 } 15911 } 15912 } 15913 } 15914 } 15915 } else if (table.getTableType() == ETableSource.xmltable) { 15916 Table functionTable = modelFactory.createXmlTable(table); 15917 TXmlTable xmlTable = table.getXmlTable(); 15918 TXmlTableParameter param = xmlTable != null ? xmlTable.getArg() : null; 15919 15920 // Output columns from COLUMNS clause 15921 if (param != null && param.getXmlTableColumns() != null) { 15922 TColumnDefinitionList defs = param.getXmlTableColumns(); 15923 for (int j = 0; j < defs.size(); j++) { 15924 TColumnDefinition def = defs.getColumn(j); 15925 TableColumn column = modelFactory.createTableColumn( 15926 functionTable, def.getColumnName(), true); 15927 if (def.getXmlTableColumnPath() != null) { 15928 column.setDisplayName( 15929 column.getName() + ":" + def.getXmlTableColumnPath()); 15930 } 15931 } 15932 } 15933 functionTable.setCreateTable(true); 15934 functionTable.setSubType(SubType.function); 15935 modelManager.bindCreateModel(table, functionTable); 15936 15937 // Source columns from PASSING (v1: many-to-many) 15938 TResultColumnList passing = null; 15939 if (param != null && param.getXmlPassingClause() != null) { 15940 passing = param.getXmlPassingClause().getPassingList(); 15941 } 15942 if (passing != null && passing.size() > 0) { 15943 columnsInExpr visitor = new columnsInExpr(); 15944 for (int p = 0; p < passing.size(); p++) { 15945 TExpression e = passing.getResultColumn(p).getExpr(); 15946 if (e != null) e.inOrderTraverse(visitor); 15947 } 15948 List<TObjectName> objectNames = visitor.getObjectNames(); 15949 List<TParseTreeNode> functions = visitor.getFunctions(); 15950 List<TParseTreeNode> constants = visitor.getConstants(); 15951 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 15952 15953 for (int j = 0; j < functionTable.getColumns().size(); j++) { 15954 TableColumn tc = functionTable.getColumns().get(j); 15955 if (functions != null && !functions.isEmpty()) 15956 analyzeFunctionDataFlowRelation(tc, functions, EffectType.function); 15957 if (subquerys != null && !subquerys.isEmpty()) 15958 analyzeSubqueryDataFlowRelation(tc, subquerys, EffectType.select); 15959 if (objectNames != null && !objectNames.isEmpty()) 15960 analyzeDataFlowRelation(tc, objectNames, EffectType.select, functions); 15961 if (constants != null && !constants.isEmpty()) 15962 analyzeConstantDataFlowRelation(tc, constants, EffectType.select, functions); 15963 } 15964 } else { 15965 ErrorInfo errorInfo = new ErrorInfo(); 15966 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 15967 errorInfo.setErrorMessage("Can't analyze XMLTABLE: missing PASSING clause."); 15968 errorInfos.add(errorInfo); 15969 } 15970 } else if (getTableLinkedColumns(table) != null && getTableLinkedColumns(table).size() > 0) { 15971 if (table.getTableType() == ETableSource.rowList && table.getRowList() != null 15972 && table.getRowList().size() > 0) { 15973 Table tableModel = modelFactory.createTable(table); 15974 for (int j = 0; j < table.getRowList().size(); j++) { 15975 TMultiTarget rowList = table.getRowList().getMultiTarget(j); 15976 for (int k = 0; k < rowList.getColumnList().size(); k++) { 15977 TResultColumn column = rowList.getColumnList().getResultColumn(k); 15978 if (column.getFieldAttr() == null) 15979 continue; 15980 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, 15981 column.getFieldAttr(), true); 15982 15983 columnsInExpr visitor = new columnsInExpr(); 15984 column.getExpr().inOrderTraverse(visitor); 15985 List<TObjectName> objectNames = visitor.getObjectNames(); 15986 List<TParseTreeNode> functions = visitor.getFunctions(); 15987 List<TParseTreeNode> constants = visitor.getConstants(); 15988 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 15989 15990 if (functions != null && !functions.isEmpty()) { 15991 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 15992 } 15993 if (subquerys != null && !subquerys.isEmpty()) { 15994 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 15995 } 15996 if (objectNames != null && !objectNames.isEmpty()) { 15997 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 15998 } 15999 if (constants != null && !constants.isEmpty()) { 16000 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, 16001 functions); 16002 } 16003 } 16004 } 16005 } else { 16006 if(table.getTableType() == ETableSource.pivoted_table) { 16007 continue; 16008 } 16009 if (table.getTableType() == ETableSource.rowList) { 16010 List<TResultColumnList> rowList = table.getValueClause().getRows(); 16011 16012 QueryTable tableModel = modelFactory.createQueryTable(table); 16013 TAliasClause aliasClause = table.getAliasClause(); 16014 if (aliasClause != null && aliasClause.getColumns() != null) { 16015 for (TObjectName column : aliasClause.getColumns()) { 16016 modelFactory.createResultColumn(tableModel, column, true); 16017 } 16018 } else { 16019 int columnCount = rowList.get(0).size(); 16020 for (int j = 1; j <= columnCount; j++) { 16021 TObjectName columnName = new TObjectName(); 16022 columnName.setString("column" + j); 16023 modelFactory.createResultColumn(tableModel, columnName, true); 16024 } 16025 } 16026 tableModel.setDetermined(true); 16027 16028 for (TResultColumnList resultColumnList : rowList) { 16029 for (int j = 0; j < resultColumnList.size(); j++) { 16030 TResultColumn resultColumn = resultColumnList.getResultColumn(j); 16031 analyzeValueColumn(tableModel.getColumns().get(j), resultColumn, EffectType.select); 16032 } 16033 } 16034 16035 } else { 16036 Table tableModel = modelFactory.createTable(table); 16037 for (int j = 0; j < getTableLinkedColumns(table).size(); j++) { 16038 TObjectName object = getTableLinkedColumns(table).getObjectName(j); 16039 16040 if (object.getDbObjectType() == EDbObjectType.variable) { 16041 continue; 16042 } 16043 16044 if (object.getColumnNameOnly().startsWith("@") 16045 && (option.getVendor() == EDbVendor.dbvmssql 16046 || option.getVendor() == EDbVendor.dbvazuresql)) { 16047 continue; 16048 } 16049 16050 if (object.getColumnNameOnly().startsWith(":") 16051 && (option.getVendor() == EDbVendor.dbvhana 16052 || option.getVendor() == EDbVendor.dbvteradata)) { 16053 continue; 16054 } 16055 16056 if (isBuiltInFunctionName(object) && isFromFunction(object)) { 16057 continue; 16058 } 16059 16060 if (!"*".equals(getColumnName(object))) { 16061 if (isStructColumn(object)) { 16062 16063 } else { 16064 if (pivotedTable != null) { 16065 ResultColumn resultColumn = getPivotedTableColumn(pivotedTable, object); 16066 if (resultColumn != null) { 16067 continue; 16068 } 16069 } 16070 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object, 16071 false); 16072 if(tableColumn == null) { 16073 continue; 16074 } 16075 if (table.getUnnestClause() != null 16076 && table.getUnnestClause().getArrayExpr() != null) { 16077 columnsInExpr visitor = new columnsInExpr(); 16078 table.getUnnestClause().getArrayExpr().inOrderTraverse(visitor); 16079 16080 List<TObjectName> objectNames = visitor.getObjectNames(); 16081 List<TParseTreeNode> functions = visitor.getFunctions(); 16082 16083 if (functions != null && !functions.isEmpty()) { 16084 analyzeFunctionDataFlowRelation(tableColumn, functions, 16085 EffectType.select); 16086 16087 } 16088 16089 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 16090 if (subquerys != null && !subquerys.isEmpty()) { 16091 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, 16092 EffectType.select); 16093 } 16094 16095 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, 16096 functions); 16097 16098 List<TParseTreeNode> constants = visitor.getConstants(); 16099 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, 16100 functions); 16101 } 16102 } 16103 } else { 16104 boolean flag = false; 16105 for (TObjectName column : getTableLinkedColumns(table)) { 16106 if ("*".equals(getColumnName(column))) { 16107 continue; 16108 } 16109 if (column.getLocation() != ESqlClause.where 16110 && column.getLocation() != ESqlClause.joinCondition) { 16111 flag = true; 16112 } 16113 } 16114 if (!flag) { 16115 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object, 16116 false); 16117 if (tableColumn != null && !tableModel.hasSQLEnv()) { 16118 tableColumn.setShowStar(true); 16119 } 16120 } 16121 } 16122 16123 } 16124 } 16125 } 16126 } 16127 else { 16128 modelFactory.createTable(table); 16129 } 16130 } 16131 16132 if (pivotedTable!=null) { 16133 for (TJoin join : stmt.getJoins()) { 16134 if (join.getTable() != null && join.getTable().getPivotedTable() != null) { 16135 if (isUnPivotedTable(join.getTable().getPivotedTable())) { 16136 analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable()); 16137 } else { 16138 analyzePivotedTable(stmt, join.getTable().getPivotedTable()); 16139 } 16140 stmtStack.pop(); 16141 return; 16142 } 16143 } 16144 } 16145 16146 if (!stmt.isCombinedQuery()) { 16147 Object queryModel = modelManager.getModel(stmt.getResultColumnList()); 16148 16149 if (queryModel == null) { 16150 TSelectSqlStatement parentStmt = getParentSetSelectStmt(stmt); 16151 if (isTopResultSet(stmt) || parentStmt == null) { 16152 ResultSet resultSetModel = modelFactory.createResultSet(stmt, 16153 isTopResultSet(stmt) && isShowTopSelectResultSet() && stmt.getIntoClause() == null); 16154 16155 createPseudoImpactRelation(stmt, resultSetModel, EffectType.select); 16156 16157 boolean isDetermined = true; 16158 Map<String, AtomicInteger> keyMap = new HashMap<String, AtomicInteger>(); 16159 Set<String> columnNames = new HashSet<String>(); 16160 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 16161 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 16162 16163 if (column.getExpr().getComparisonType() == EComparisonType.equals 16164 && column.getExpr().getLeftOperand().getObjectOperand() != null) { 16165 TObjectName columnObject = column.getExpr().getLeftOperand().getObjectOperand(); 16166 16167 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 16168 columnObject); 16169 if (columnObject.getDbObjectType() == EDbObjectType.variable) { 16170 Table variable = modelManager 16171 .getTableByName(DlineageUtil.getTableFullName(columnObject.toString())); 16172 if (variable != null) { 16173 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16174 relation.setEffectType(EffectType.select); 16175 TableColumn columnModel = variable.getColumns().get(0); 16176 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 16177 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 16178 } else { 16179 variable = modelFactory.createVariable(columnObject); 16180 variable.setCreateTable(true); 16181 variable.setSubType(SubType.record); 16182 TObjectName variableProperties = new TObjectName(); 16183 variableProperties.setString("*"); 16184 TableColumn variableProperty = modelFactory.createTableColumn(variable, 16185 variableProperties, true); 16186 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16187 relation.setEffectType(EffectType.select); 16188 relation.setTarget(new TableColumnRelationshipElement(variableProperty)); 16189 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 16190 } 16191 } 16192 16193 columnsInExpr visitor = new columnsInExpr(); 16194 column.getExpr().getRightOperand().inOrderTraverse(visitor); 16195 16196 List<TObjectName> objectNames = visitor.getObjectNames(); 16197 List<TParseTreeNode> functions = visitor.getFunctions(); 16198 16199 if (functions != null && !functions.isEmpty()) { 16200 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.select); 16201 16202 } 16203 16204 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 16205 if (subquerys != null && !subquerys.isEmpty()) { 16206 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 16207 } 16208 16209 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 16210 16211 List<TParseTreeNode> constants = visitor.getConstants(); 16212 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 16213 } else { 16214 if (column.getFieldAttr() != null && isStructColumn(column.getFieldAttr())) { 16215 Table table = modelFactory.createTable(column.getFieldAttr().getSourceTable()); 16216 for (int j = 0; j < table.getColumns().size(); j++) { 16217 TObjectName columnName = new TObjectName(); 16218 if (table.getColumns().get(j).getName().equals(table.getAlias())) { 16219 if (!SQLUtil.isEmpty(column.getColumnAlias())) { 16220 columnName.setString(column.getColumnAlias()); 16221 } else { 16222 columnName.setString(table.getColumns().get(j).getName()); 16223 } 16224 } else { 16225 columnName.setString( 16226 table.getAlias() + "." + table.getColumns().get(j).getName()); 16227 } 16228 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 16229 columnName); 16230 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 16231 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16232 relationship.addSource( 16233 new TableColumnRelationshipElement(table.getColumns().get(j))); 16234 } 16235 } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.struct_t) { 16236 Function function = (Function) createFunction(column.getExpr().getFunctionCall()); 16237 String functionName = getResultSetName(function); 16238 for (int j = 0; j < function.getColumns().size(); j++) { 16239 TObjectName columnName = new TObjectName(); 16240 if (column.getAliasClause() != null) { 16241 columnName.setString(column.getAliasClause() + "." 16242 + function.getColumns().get(j).getName()); 16243 } 16244 else { 16245 columnName.setString(functionName + "." 16246 + function.getColumns().get(j).getName()); 16247 } 16248 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 16249 columnName); 16250 resultColumn.setStruct(true); 16251 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 16252 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16253 relationship.addSource( 16254 new ResultColumnRelationshipElement(function.getColumns().get(j))); 16255 } 16256 } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.array_t) { 16257 Function function = (Function) createFunction(column.getExpr().getFunctionCall()); 16258 String functionName = getResultSetName(function); 16259 if (function.getColumns().size() == 1) { 16260 // Scalar result inside ARRAY() - use just alias as column name 16261 TObjectName columnName = new TObjectName(); 16262 if (column.getAliasClause() != null) { 16263 columnName.setString(column.getAliasClause().toString()); 16264 } else { 16265 columnName.setString(functionName); 16266 } 16267 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 16268 columnName); 16269 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 16270 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16271 relationship.addSource( 16272 new ResultColumnRelationshipElement(function.getColumns().get(0))); 16273 } else { 16274 for (int j = 0; j < function.getColumns().size(); j++) { 16275 TObjectName columnName = new TObjectName(); 16276 if (column.getAliasClause() != null) { 16277 columnName.setString(column.getAliasClause() + "." 16278 + getColumnNameOnly(function.getColumns().get(j).getName())); 16279 } 16280 else { 16281 columnName.setString(functionName + "." 16282 + getColumnNameOnly(function.getColumns().get(j).getName())); 16283 } 16284 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 16285 columnName); 16286 resultColumn.setStruct(true); 16287 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 16288 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16289 relationship.addSource( 16290 new ResultColumnRelationshipElement(function.getColumns().get(j))); 16291 } 16292 } 16293 } else if (column.getExpr().getExprList() != null && column.getExpr().getExpressionType() == EExpressionType.array_t) { 16294 if(column.getExpr().getObjectOperand()!=null) { 16295 TObjectName exprColumnName = column.getExpr().getObjectOperand(); 16296 Table table = modelFactory.createTable(exprColumnName.getSourceTable()); 16297 for (int z = 0; z < table.getColumns().size(); z++) { 16298 TableColumn tableColumn = table.getColumns().get(z); 16299 if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) { 16300 TObjectName columnName = new TObjectName(); 16301 if (column.getAliasClause() != null) { 16302 columnName.setString(column.getAliasClause().toString()); 16303 } else { 16304 columnName 16305 .setString(getColumnNameOnly(columnName.toString())); 16306 } 16307 ResultColumn resultColumn = modelFactory 16308 .createResultColumn(resultSetModel, columnName); 16309 resultColumn.setStruct(true); 16310 DataFlowRelationship relationship = modelFactory 16311 .createDataFlowRelation(); 16312 relationship.setTarget( 16313 new ResultColumnRelationshipElement(resultColumn)); 16314 relationship.addSource(new TableColumnRelationshipElement( 16315 tableColumn)); 16316 } 16317 } 16318 } 16319 else { 16320 for (int j = 0; j < column.getExpr().getExprList().size(); j++) { 16321 TExpression expression = column.getExpr().getExprList().getExpression(j); 16322 if(expression.getExpressionType() == EExpressionType.function_t) { 16323 Function function = (Function)createFunction(expression.getFunctionCall()); 16324 String functionName = getResultSetName(function); 16325 if (function != null && function.getColumns() != null) { 16326 if (function.getColumns().size() == 1) { 16327 // Scalar function inside ARRAY[] (e.g., ARRAY[TO_JSON_STRING(col)]) 16328 // Use just the alias as column name, not alias.functionName 16329 TObjectName columnName = new TObjectName(); 16330 if (column.getAliasClause() != null) { 16331 columnName.setString(column.getAliasClause().toString()); 16332 } else { 16333 columnName.setString(functionName); 16334 } 16335 ResultColumn resultColumn = modelFactory 16336 .createResultColumn(resultSetModel, columnName); 16337 DataFlowRelationship relationship = modelFactory 16338 .createDataFlowRelation(); 16339 relationship.setTarget( 16340 new ResultColumnRelationshipElement(resultColumn)); 16341 relationship.addSource(new ResultColumnRelationshipElement( 16342 function.getColumns().get(0))); 16343 } else { 16344 // Multi-column (struct-like) function - use dotted naming 16345 for (int x = 0; x < function.getColumns().size(); x++) { 16346 TObjectName columnName = new TObjectName(); 16347 if (column.getAliasClause() != null) { 16348 columnName.setString(column.getAliasClause() + "." 16349 + getColumnNameOnly( 16350 function.getColumns().get(x).getName())); 16351 } else { 16352 columnName.setString( 16353 functionName + "." + getColumnNameOnly( 16354 function.getColumns().get(x).getName())); 16355 } 16356 ResultColumn resultColumn = modelFactory 16357 .createResultColumn(resultSetModel, columnName); 16358 resultColumn.setStruct(true); 16359 DataFlowRelationship relationship = modelFactory 16360 .createDataFlowRelation(); 16361 relationship.setTarget( 16362 new ResultColumnRelationshipElement(resultColumn)); 16363 relationship.addSource(new ResultColumnRelationshipElement( 16364 function.getColumns().get(x))); 16365 } 16366 } 16367 } 16368 } 16369 else if(expression.getExpressionType() == EExpressionType.simple_object_name_t) { 16370 TObjectName exprColumnName = expression.getObjectOperand(); 16371 Table table = modelFactory.createTable(exprColumnName.getSourceTable()); 16372 for (int z = 0; z < table.getColumns().size(); z++) { 16373 TableColumn tableColumn = table.getColumns().get(z); 16374 if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) { 16375 TObjectName columnName = new TObjectName(); 16376 if (column.getAliasClause() != null) { 16377 columnName.setString(column.getAliasClause().toString()); 16378 } else { 16379 columnName 16380 .setString(getColumnNameOnly(columnName.toString())); 16381 } 16382 ResultColumn resultColumn = modelFactory 16383 .createResultColumn(resultSetModel, columnName); 16384 resultColumn.setStruct(true); 16385 DataFlowRelationship relationship = modelFactory 16386 .createDataFlowRelation(); 16387 relationship.setTarget( 16388 new ResultColumnRelationshipElement(resultColumn)); 16389 relationship.addSource(new TableColumnRelationshipElement( 16390 tableColumn)); 16391 } 16392 } 16393 } 16394 } 16395 } 16396 } else { 16397 if ("*".equals(column.getColumnNameOnly())) { 16398 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 16399 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 16400 if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) { 16401 for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) { 16402 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 16403 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 16404 } 16405 } 16406 16407 TObjectName columnObject = column.getFieldAttr(); 16408 List<TTable> sourceTables = columnObject.getSourceTableList(); 16409 if (sourceTables != null && !sourceTables.isEmpty()) { 16410 boolean[] determine = new boolean[sourceTables.size()]; 16411 for (int k = 0; k < sourceTables.size(); k++) { 16412 TTable sourceTable = sourceTables.get(k); 16413 Object tableModel = modelManager.getModel(sourceTable); 16414 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 16415 Table table = (Table) tableModel; 16416 for (int j = 0; j < table.getColumns().size(); j++) { 16417 TableColumn tableColumn = table.getColumns().get(j); 16418 if (column.getExceptColumnList() != null) { 16419 boolean except = false; 16420 for (TObjectName objectName : column.getExceptColumnList()) { 16421 if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) { 16422 except = true; 16423 break; 16424 } 16425 } 16426 if (!except && tableColumn.isStruct()) { 16427 List<String> names = SQLUtil 16428 .parseNames(tableColumn.getName()); 16429 for (String name : names) { 16430 for (TObjectName objectName : column 16431 .getExceptColumnList()) { 16432 if (getColumnName(objectName.toString()) 16433 .equals(getColumnName(name))) { 16434 except = true; 16435 break; 16436 } 16437 } 16438 if (except) { 16439 break; 16440 } 16441 } 16442 } 16443 if(except){ 16444 continue; 16445 } 16446 } 16447 16448 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 16449 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 16450 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 16451 Transform transform = new Transform(); 16452 transform.setType(Transform.EXPRESSION); 16453 TObjectName expression = new TObjectName(); 16454 expression.setString(expr.first); 16455 transform.setCode(expression); 16456 resultColumn.setTransform(transform); 16457 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 16458 } 16459 else { 16460 String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()); 16461 //bigquery 16462 boolean exist = false; 16463 if (!columnName.matches("(?i)f\\d+_")) { 16464 if (!keyMap.containsKey(columnName)) { 16465 keyMap.put(columnName, new AtomicInteger(0)); 16466 } else { 16467 while (columnNames.contains(columnName)) { 16468 if(columnName.indexOf("*") == -1 && stmt.toString().matches("(?is).*using\\s*\\(\\s*"+columnName+"\\s*\\).*")) { 16469 exist = true; 16470 break; 16471 } else if (keyMap.containsKey(columnName)) { 16472 int index = keyMap.get(columnName) 16473 .incrementAndGet(); 16474 columnName = columnName + index; 16475 } 16476 } 16477 } 16478 columnNames.add(columnName); 16479 } 16480 if (exist) { 16481 String targetColumn = columnName; 16482 DataFlowRelationship relation = modelFactory 16483 .createDataFlowRelation(); 16484 relation.setEffectType(EffectType.select); 16485 relation.setTarget(new ResultColumnRelationshipElement( 16486 resultSetModel.getColumns().stream() 16487 .filter(t -> t.getName() 16488 .equalsIgnoreCase(targetColumn)) 16489 .findFirst().get())); 16490 relation.addSource(new TableColumnRelationshipElement( 16491 tableColumn)); 16492 continue; 16493 } 16494 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()) 16495 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) { 16496 columnName = tableColumn.getName(); 16497 } 16498 ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName); 16499 resultColumn.setStruct(tableColumn.isStruct()); 16500 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16501 relation.setEffectType(EffectType.select); 16502 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16503 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 16504 } 16505 } 16506 determine[k] = true; 16507 continue; 16508 } 16509 else if (tableModel instanceof ResultSet && ((ResultSet) tableModel).isDetermined()) { 16510 ResultSet table = (ResultSet) tableModel; 16511 for (int j = 0; j < table.getColumns().size(); j++) { 16512 ResultColumn tableColumn = table.getColumns().get(j); 16513 if (column.getExceptColumnList() != null) { 16514 boolean except = false; 16515 for (TObjectName objectName : column.getExceptColumnList()) { 16516 if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) { 16517 except = true; 16518 break; 16519 } 16520 } 16521 if (!except && tableColumn.isStruct()) { 16522 List<String> names = SQLUtil 16523 .parseNames(tableColumn.getName()); 16524 for (String name : names) { 16525 for (TObjectName objectName : column 16526 .getExceptColumnList()) { 16527 if (getColumnName(objectName.toString()) 16528 .equals(getColumnName(name))) { 16529 except = true; 16530 break; 16531 } 16532 } 16533 if (except) { 16534 break; 16535 } 16536 } 16537 } 16538 if(except){ 16539 continue; 16540 } 16541 } 16542 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 16543 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 16544 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 16545 Transform transform = new Transform(); 16546 transform.setType(Transform.EXPRESSION); 16547 TObjectName expression = new TObjectName(); 16548 expression.setString(expr.first); 16549 transform.setCode(expression); 16550 resultColumn.setTransform(transform); 16551 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 16552 } 16553 else if(tableColumn.getRefColumnName()!=null) { 16554 ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, tableColumn.getRefColumnName()); 16555 if(tableColumn.isStruct()) { 16556 resultColumn.setStruct(true); 16557 } 16558 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16559 relation.setEffectType(EffectType.select); 16560 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16561 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 16562 } 16563 else { 16564 String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()); 16565 //bigquery 16566 if (!columnName.matches("(?i)f\\d+_")) { 16567 if (!keyMap.containsKey(columnName)) { 16568 keyMap.put(columnName, new AtomicInteger(0)); 16569 } else { 16570 while (columnNames.contains(columnName)) { 16571 int index = keyMap.get(columnName) 16572 .incrementAndGet(); 16573 columnName = columnName + index; 16574 } 16575 } 16576 columnNames.add(columnName); 16577 } 16578 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()) 16579 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) { 16580 columnName = tableColumn.getName(); 16581 } 16582 if (modelManager.getModel(column) instanceof ResultColumn) { 16583 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16584 relation.setEffectType(EffectType.select); 16585 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn)modelManager.getModel(column))); 16586 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 16587 } 16588 else { 16589 ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName); 16590 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16591 relation.setEffectType(EffectType.select); 16592 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16593 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 16594 } 16595 } 16596 } 16597 determine[k] = true; 16598 continue; 16599 } 16600 else { 16601 ResultColumn resultColumn = modelFactory 16602 .createResultColumn(resultSetModel, column); 16603 if (tableModel instanceof Function) { 16604 16605 } else { 16606 TObjectName[] columns = modelManager 16607 .getTableColumns(sourceTable); 16608 for (int j = 0; j < columns.length; j++) { 16609 TObjectName columnName = columns[j]; 16610 if (columnName == null 16611 || "*".equals(getColumnName(columnName))) { 16612 continue; 16613 } 16614 if (isStructColumn(columnName)) { 16615 continue; 16616 } 16617 16618 resultColumn.bindStarLinkColumn(columnName); 16619 if (column.getExceptColumnList() != null) { 16620 for (TObjectName objectName : column 16621 .getExceptColumnList()) { 16622 resultColumn.unbindStarLinkColumn(objectName); 16623 } 16624 } 16625 } 16626 if (tableModel instanceof ResultSet) { 16627 ResultSet queryTable = (ResultSet) tableModel; 16628 if (!containStarColumn(queryTable)) { 16629 resultColumn.setShowStar(false); 16630 } 16631 } 16632 if (tableModel instanceof Table) { 16633 Table table = (Table) tableModel; 16634 if (table.isCreateTable()) { 16635 resultColumn.setShowStar(false); 16636 } 16637 } 16638 } 16639 } 16640 } 16641 if(!Arrays.toString(determine).contains("false")) { 16642 continue; 16643 } 16644 } else { 16645 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 16646 TTableList tables = stmt.getTables(); 16647 for (int k = 0; k < tables.size(); k++) { 16648 TTable table = tables.getTable(k); 16649 TObjectName[] columns = modelManager.getTableColumns(table); 16650 for (int j = 0; j < columns.length; j++) { 16651 TObjectName columnName = columns[j]; 16652 if (columnName == null) { 16653 continue; 16654 } 16655 if ("*".equals(getColumnName(columnName))) { 16656 if (modelManager.getModel(table) instanceof Table) { 16657 Table tableModel = (Table) modelManager.getModel(table); 16658 if (tableModel != null 16659 && !tableModel.getColumns().isEmpty()) { 16660 for (TableColumn item : tableModel.getColumns()) { 16661 resultColumn 16662 .bindStarLinkColumn(item.getColumnObject()); 16663 if (table.getSubquery() == null 16664 && table.getCTE() == null 16665 && !tableModel.isCreateTable()) { 16666 resultColumn.setShowStar(true); 16667 } 16668 } 16669 } 16670 } else if (modelManager.getModel(table) instanceof QueryTable) { 16671 QueryTable tableModel = (QueryTable) modelManager 16672 .getModel(table); 16673 if (tableModel != null 16674 && !tableModel.getColumns().isEmpty()) { 16675 for (ResultColumn item : tableModel.getColumns()) { 16676 if (item.hasStarLinkColumn()) { 16677 for (TObjectName starLinkColumn : item 16678 .getStarLinkColumnList()) { 16679 resultColumn 16680 .bindStarLinkColumn(starLinkColumn); 16681 } 16682 } else if (item 16683 .getColumnObject() instanceof TObjectName) { 16684 resultColumn.bindStarLinkColumn( 16685 (TObjectName) item.getColumnObject()); 16686 } else if (item 16687 .getColumnObject() instanceof TResultColumn) { 16688 TResultColumn queryTableColumn = (TResultColumn) item 16689 .getColumnObject(); 16690 TObjectName tableColumnObject = queryTableColumn 16691 .getFieldAttr(); 16692 if (tableColumnObject != null) { 16693 resultColumn.bindStarLinkColumn( 16694 tableColumnObject); 16695 } else if (queryTableColumn 16696 .getAliasClause() != null && !item.isStruct()) { 16697 resultColumn.bindStarLinkColumn( 16698 queryTableColumn.getAliasClause() 16699 .getAliasName()); 16700 } 16701 } 16702 } 16703 } 16704 } 16705 continue; 16706 } 16707 resultColumn.bindStarLinkColumn(columnName); 16708 } 16709 } 16710 } 16711 isDetermined = false; 16712 } 16713 else { 16714 if(column.getAliasClause()!=null && column.getAliasClause().getColumns()!=null) { 16715 for(TObjectName aliasColumn: column.getAliasClause().getColumns()) { 16716 modelFactory.createResultColumn(resultSetModel, aliasColumn); 16717 } 16718 } 16719 else { 16720 modelFactory.createResultColumn(resultSetModel, column); 16721 } 16722 } 16723 analyzeResultColumn(column, EffectType.select); 16724 } 16725 } 16726 } 16727 if (isDetermined) { 16728 resultSetModel.setDetermined(isDetermined); 16729 } 16730 } 16731 16732 TSelectSqlStatement parent = getParentSetSelectStmt(stmt); 16733 if (parent != null && parent.getSetOperatorType() != ESetOperatorType.none) { 16734 ResultSet resultSetModel = modelFactory.createResultSet(stmt, false); 16735 if(queryModel == null) { 16736 queryModel = resultSetModel; 16737 } 16738 16739 createPseudoImpactRelation(stmt, resultSetModel, EffectType.select); 16740 16741 boolean isDetermined = true; 16742 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 16743 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 16744 if ("*".equals(column.getColumnNameOnly())) { 16745 16746 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 16747 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 16748 if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) { 16749 for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) { 16750 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 16751 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 16752 } 16753 } 16754 16755 TObjectName columnObject = column.getFieldAttr(); 16756 TTable sourceTable = columnObject.getSourceTable(); 16757 if (sourceTable != null) { 16758 Object tableModel = modelManager.getModel(sourceTable); 16759 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 16760 Table table = (Table) tableModel; 16761 for (int j = 0; j < table.getColumns().size(); j++) { 16762 TableColumn tableColumn = table.getColumns().get(j); 16763 if (column.getExceptColumnList() != null) { 16764 boolean except = false; 16765 for (TObjectName objectName : column.getExceptColumnList()) { 16766 if (getColumnName(objectName.toString()) 16767 .equals(getColumnName(tableColumn.getName()))) { 16768 except = true; 16769 break; 16770 } 16771 } 16772 if (!except && tableColumn.isStruct()) { 16773 List<String> names = SQLUtil 16774 .parseNames(tableColumn.getName()); 16775 for (String name : names) { 16776 for (TObjectName objectName : column 16777 .getExceptColumnList()) { 16778 if (getColumnName(objectName.toString()) 16779 .equals(getColumnName(name))) { 16780 except = true; 16781 break; 16782 } 16783 } 16784 if (except) { 16785 break; 16786 } 16787 } 16788 } 16789 if (except) { 16790 continue; 16791 } 16792 } 16793 16794 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 16795 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 16796 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 16797 Transform transform = new Transform(); 16798 transform.setType(Transform.EXPRESSION); 16799 TObjectName expression = new TObjectName(); 16800 expression.setString(expr.first); 16801 transform.setCode(expression); 16802 resultColumn.setTransform(transform); 16803 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 16804 } 16805 else { 16806 ResultColumn resultColumn = modelFactory.createStarResultColumn( 16807 resultSetModel, column, tableColumn.getName()); 16808 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16809 relation.setEffectType(EffectType.select); 16810 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16811 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 16812 } 16813 } 16814 continue; 16815 } else if (tableModel instanceof ResultSet 16816 && ((ResultSet) tableModel).isDetermined()) { 16817 ResultSet table = (ResultSet) tableModel; 16818 for (int j = 0; j < table.getColumns().size(); j++) { 16819 ResultColumn tableColumn = table.getColumns().get(j); 16820 if (column.getExceptColumnList() != null) { 16821 boolean except = false; 16822 for (TObjectName objectName : column.getExceptColumnList()) { 16823 if (getColumnName(objectName.toString()) 16824 .equals(getColumnName(tableColumn.getName()))) { 16825 except = true; 16826 break; 16827 } 16828 } 16829 if (!except && tableColumn.isStruct()) { 16830 List<String> names = SQLUtil 16831 .parseNames(tableColumn.getName()); 16832 for (String name : names) { 16833 for (TObjectName objectName : column 16834 .getExceptColumnList()) { 16835 if (getColumnName(objectName.toString()) 16836 .equals(getColumnName(name))) { 16837 except = true; 16838 break; 16839 } 16840 } 16841 if (except) { 16842 break; 16843 } 16844 } 16845 } 16846 if (except) { 16847 continue; 16848 } 16849 } 16850 16851 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 16852 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 16853 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 16854 Transform transform = new Transform(); 16855 transform.setType(Transform.EXPRESSION); 16856 TObjectName expression = new TObjectName(); 16857 expression.setString(expr.first); 16858 transform.setCode(expression); 16859 resultColumn.setTransform(transform); 16860 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 16861 } 16862 else if (tableColumn.getRefColumnName() != null) { 16863 ResultColumn resultColumn = modelFactory.createStarResultColumn( 16864 (ResultSet)queryModel, column, tableColumn.getRefColumnName()); 16865 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16866 relation.setEffectType(EffectType.select); 16867 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16868 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 16869 } else { 16870 ResultColumn resultColumn = modelFactory.createStarResultColumn( 16871 resultSetModel, column, tableColumn.getName()); 16872 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16873 relation.setEffectType(EffectType.select); 16874 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 16875 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 16876 } 16877 } 16878 continue; 16879 } 16880 else { 16881 isDetermined = false; 16882 } 16883 } 16884 16885 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 16886 16887 if (columnObject.getTableToken() != null && sourceTable != null) { 16888 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 16889 for (int j = 0; j < columns.length; j++) { 16890 TObjectName columnName = columns[j]; 16891 if (columnName == null || "*".equals(getColumnName(columnName))) { 16892 continue; 16893 } 16894 resultColumn.bindStarLinkColumn(columnName); 16895 } 16896 16897 if (modelManager.getModel(sourceTable) instanceof Table) { 16898 Table tableModel = (Table) modelManager.getModel(sourceTable); 16899 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 16900 for (TableColumn item : tableModel.getColumns()) { 16901 if ("*".equals(getColumnName(item.getColumnObject()))) { 16902 continue; 16903 } 16904 resultColumn.bindStarLinkColumn(item.getColumnObject()); 16905 } 16906 } 16907 } else if (modelManager.getModel(sourceTable) instanceof QueryTable) { 16908 QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable); 16909 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 16910 for (ResultColumn item : tableModel.getColumns()) { 16911 if (item.hasStarLinkColumn()) { 16912 for (TObjectName starLinkColumn : item.getStarLinkColumnList()) { 16913 if ("*".equals(getColumnName(starLinkColumn))) { 16914 continue; 16915 } 16916 resultColumn.bindStarLinkColumn(starLinkColumn); 16917 } 16918 } else if (item.getColumnObject() instanceof TObjectName) { 16919 TObjectName starLinkColumn = (TObjectName) item.getColumnObject(); 16920 if ("*".equals(getColumnName(starLinkColumn))) { 16921 continue; 16922 } 16923 resultColumn.bindStarLinkColumn(starLinkColumn); 16924 } 16925 } 16926 } 16927 } 16928 16929 } else { 16930 TTableList tables = stmt.getTables(); 16931 for (int k = 0; k < tables.size(); k++) { 16932 TTable table = tables.getTable(k); 16933 TObjectName[] columns = modelManager.getTableColumns(table); 16934 for (int j = 0; j < columns.length; j++) { 16935 TObjectName columnName = columns[j]; 16936 if (columnName == null) { 16937 continue; 16938 } 16939 if ("*".equals(getColumnName(columnName))) { 16940 if (modelManager.getModel(table) instanceof Table) { 16941 Table tableModel = (Table) modelManager.getModel(table); 16942 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 16943 for (TableColumn item : tableModel.getColumns()) { 16944 resultColumn.bindStarLinkColumn(item.getColumnObject()); 16945 } 16946 } 16947 } else if (modelManager.getModel(table) instanceof QueryTable) { 16948 QueryTable tableModel = (QueryTable) modelManager.getModel(table); 16949 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 16950 for (ResultColumn item : tableModel.getColumns()) { 16951 if (item.hasStarLinkColumn()) { 16952 for (TObjectName starLinkColumn : item 16953 .getStarLinkColumnList()) { 16954 resultColumn.bindStarLinkColumn(starLinkColumn); 16955 } 16956 } else if (item.getColumnObject() instanceof TObjectName) { 16957 resultColumn.bindStarLinkColumn( 16958 (TObjectName) item.getColumnObject()); 16959 } else if (item 16960 .getColumnObject() instanceof TResultColumn) { 16961 TResultColumn queryTableColumn = (TResultColumn) item 16962 .getColumnObject(); 16963 TObjectName tableColumnObject = queryTableColumn 16964 .getFieldAttr(); 16965 if (tableColumnObject != null) { 16966 resultColumn.bindStarLinkColumn(tableColumnObject); 16967 } else if (queryTableColumn.getAliasClause() != null) { 16968 resultColumn.bindStarLinkColumn(queryTableColumn 16969 .getAliasClause().getAliasName()); 16970 } 16971 } 16972 } 16973 } 16974 } 16975 16976 continue; 16977 } 16978 resultColumn.bindStarLinkColumn(columnName); 16979 } 16980 } 16981 } 16982 } 16983 else { 16984 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 16985 } 16986 analyzeResultColumn(column, EffectType.select); 16987 16988 } 16989 16990 resultSetModel.setDetermined(isDetermined); 16991 } 16992 } else { 16993 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 16994 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 16995 16996 if (!(queryModel instanceof ResultSet)) { 16997 continue; 16998 } 16999 17000 ResultSet resultSetModel = (ResultSet)queryModel; 17001 17002 if ("*".equals(column.getColumnNameOnly())) { 17003 TObjectName columnObject = column.getFieldAttr(); 17004 TTable sourceTable = columnObject.getSourceTable(); 17005 if (column.toString().indexOf(".") == -1 && stmt.getTables().size() > 1) { 17006 sourceTable = null; 17007 } 17008 if (sourceTable != null) { 17009 { 17010 Object tableModel = modelManager.getModel(sourceTable); 17011 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 17012 Table table = (Table) tableModel; 17013 for (int j = 0; j < table.getColumns().size(); j++) { 17014 TableColumn tableColumn = table.getColumns().get(j); 17015 if (column.getExceptColumnList() != null) { 17016 boolean except = false; 17017 for (TObjectName objectName : column.getExceptColumnList()) { 17018 if (getColumnName(objectName.toString()) 17019 .equals(getColumnName(tableColumn.getName()))) { 17020 except = true; 17021 break; 17022 } 17023 } 17024 if (!except && tableColumn.isStruct()) { 17025 List<String> names = SQLUtil 17026 .parseNames(tableColumn.getName()); 17027 for (String name : names) { 17028 for (TObjectName objectName : column 17029 .getExceptColumnList()) { 17030 if (getColumnName(objectName.toString()) 17031 .equals(getColumnName(name))) { 17032 except = true; 17033 break; 17034 } 17035 } 17036 if (except) { 17037 break; 17038 } 17039 } 17040 } 17041 if (except) { 17042 continue; 17043 } 17044 } 17045 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17046 resultSetModel, column, tableColumn.getName()); 17047 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17048 relation.setEffectType(EffectType.select); 17049 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17050 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 17051 } 17052 if(stmt.getResultColumnList().size() == 1) { 17053 resultSetModel.setDetermined(true); 17054 } 17055 else { 17056 int starCount = 0; 17057 for (int j = 0; j < stmt.getResultColumnList().size(); j++) { 17058 if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly() 17059 .endsWith("*")) { 17060 starCount += 1; 17061 } 17062 } 17063 if (starCount <= 1) { 17064 resultSetModel.setDetermined(true); 17065 } 17066 } 17067 continue; 17068 } else if (tableModel instanceof ResultSet 17069 && ((ResultSet) tableModel).isDetermined()) { 17070 ResultSet table = (ResultSet) tableModel; 17071 for (int j = 0; j < table.getColumns().size(); j++) { 17072 ResultColumn tableColumn = table.getColumns().get(j); 17073 if (column.getExceptColumnList() != null) { 17074 boolean except = false; 17075 for (TObjectName objectName : column.getExceptColumnList()) { 17076 if (getColumnName(objectName.toString()) 17077 .equals(getColumnName(tableColumn.getName()))) { 17078 except = true; 17079 break; 17080 } 17081 } 17082 if (!except && tableColumn.isStruct()) { 17083 List<String> names = SQLUtil 17084 .parseNames(tableColumn.getName()); 17085 for (String name : names) { 17086 for (TObjectName objectName : column 17087 .getExceptColumnList()) { 17088 if (getColumnName(objectName.toString()) 17089 .equals(getColumnName(name))) { 17090 except = true; 17091 break; 17092 } 17093 } 17094 if (except) { 17095 break; 17096 } 17097 } 17098 } 17099 if (except) { 17100 continue; 17101 } 17102 } 17103 if (tableColumn.getRefColumnName() != null) { 17104 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17105 (ResultSet)queryModel, column, tableColumn.getRefColumnName()); 17106 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17107 relation.setEffectType(EffectType.select); 17108 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17109 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17110 } else { 17111 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17112 resultSetModel, column, tableColumn.getName()); 17113 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17114 relation.setEffectType(EffectType.select); 17115 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17116 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17117 } 17118 } 17119 if(stmt.getResultColumnList().size() == 1) { 17120 resultSetModel.setDetermined(true); 17121 } 17122 else { 17123 int starCount = 0; 17124 for (int j = 0; j < stmt.getResultColumnList().size(); j++) { 17125 if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly() 17126 .endsWith("*")) { 17127 starCount += 1; 17128 } 17129 } 17130 if (starCount <= 1) { 17131 resultSetModel.setDetermined(true); 17132 } 17133 } 17134 continue; 17135 } 17136 } 17137 17138 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17139 if (modelManager.getModel(sourceTable) instanceof Table) { 17140 Table tableModel = (Table) modelManager.getModel(sourceTable); 17141 if (tableModel != null) { 17142 modelFactory.createTableColumn(tableModel, columnObject, false); 17143 } 17144 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 17145 for (int j = 0; j < columns.length; j++) { 17146 TObjectName columnName = columns[j]; 17147 if (columnName == null || "*".equals(getColumnName(columnName))) { 17148 continue; 17149 } 17150 resultColumn.bindStarLinkColumn(columnName); 17151 } 17152 17153 if (tableModel.getColumns() != null) { 17154 for (int j = 0; j < tableModel.getColumns().size(); j++) { 17155 TableColumn tableColumn = tableModel.getColumns().get(j); 17156 TObjectName columnName = tableColumn.getColumnObject(); 17157 if (columnName == null || "*".equals(getColumnName(columnName))) { 17158 continue; 17159 } 17160 resultColumn.bindStarLinkColumn(columnName); 17161 } 17162 } 17163 } else if (modelManager.getModel(sourceTable) instanceof QueryTable) { 17164 QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable); 17165 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17166 for (ResultColumn item : tableModel.getColumns()) { 17167 if (item.hasStarLinkColumn()) { 17168 for (TObjectName starLinkColumn : item.getStarLinkColumnList()) { 17169 resultColumn.bindStarLinkColumn(starLinkColumn); 17170 } 17171 } else if (item.getColumnObject() instanceof TObjectName) { 17172 resultColumn.bindStarLinkColumn((TObjectName) item.getColumnObject()); 17173 } else if (item.getColumnObject() instanceof TResultColumn) { 17174 TResultColumn queryTableColumn = (TResultColumn) item.getColumnObject(); 17175 TObjectName tableColumnObject = queryTableColumn.getFieldAttr(); 17176 if (tableColumnObject != null) { 17177 resultColumn.bindStarLinkColumn(tableColumnObject); 17178 } else if (queryTableColumn.getAliasClause() != null) { 17179 resultColumn.bindStarLinkColumn( 17180 queryTableColumn.getAliasClause().getAliasName()); 17181 } 17182 } 17183 } 17184 } 17185 } 17186 } else { 17187 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17188 TTableList tables = stmt.getTables(); 17189 for (int k = 0; k < tables.size(); k++) { 17190 TTable table = tables.getTable(k); 17191 TObjectName[] columns = modelManager.getTableColumns(table); 17192 for (int j = 0; j < columns.length; j++) { 17193 TObjectName columnName = columns[j]; 17194 if (columnName == null) { 17195 continue; 17196 } 17197 if ("*".equals(getColumnName(columnName))) { 17198 if (modelManager.getModel(table) instanceof Table) { 17199 Table tableModel = (Table) modelManager.getModel(table); 17200 if (tableModel != null) { 17201 modelFactory.createTableColumn(tableModel, columnName, false); 17202 } 17203 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17204 for (int z = 0; z < tableModel.getColumns().size(); z++) { 17205 resultColumn.bindStarLinkColumn( 17206 tableModel.getColumns().get(z).getColumnObject()); 17207 } 17208 } 17209 } else if (modelManager.getModel(table) instanceof QueryTable) { 17210 QueryTable tableModel = (QueryTable) modelManager.getModel(table); 17211 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17212 for (ResultColumn item : tableModel.getColumns()) { 17213 if (item.hasStarLinkColumn()) { 17214 for (TObjectName starLinkColumn : item 17215 .getStarLinkColumnList()) { 17216 resultColumn.bindStarLinkColumn(starLinkColumn); 17217 } 17218 } else if (item.getColumnObject() instanceof TObjectName) { 17219 resultColumn.bindStarLinkColumn( 17220 (TObjectName) item.getColumnObject()); 17221 } else if (item.getColumnObject() instanceof TResultColumn) { 17222 TResultColumn queryTableColumn = (TResultColumn) item 17223 .getColumnObject(); 17224 TObjectName tableColumnObject = queryTableColumn 17225 .getFieldAttr(); 17226 if (tableColumnObject != null) { 17227 resultColumn.bindStarLinkColumn(tableColumnObject); 17228 } else if (queryTableColumn.getAliasClause() != null) { 17229 resultColumn.bindStarLinkColumn(queryTableColumn 17230 .getAliasClause().getAliasName()); 17231 } 17232 } 17233 } 17234 } 17235 } 17236 continue; 17237 } 17238 resultColumn.bindStarLinkColumn(columnName); 17239 } 17240 } 17241 } 17242 } 17243 else { 17244 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17245 } 17246 17247 analyzeResultColumn(column, EffectType.select); 17248 17249 } 17250 17251 if (queryModel instanceof ResultSet) { 17252 boolean isDetermined = true; 17253 ResultSet resultSet = (ResultSet) queryModel; 17254 for (ResultColumn column : resultSet.getColumns()) { 17255 if (column.getName().endsWith("*")) { 17256 isDetermined = false; 17257 break; 17258 } 17259 } 17260 if (isDetermined) { 17261 resultSet.setDetermined(isDetermined); 17262 } 17263 } 17264 } 17265 } 17266 17267 17268 analyzeSelectIntoClause(stmt); 17269 17270 17271 if (stmt.getJoins() != null && stmt.getJoins().size() > 0) { 17272 for (int i = 0; i < stmt.getJoins().size(); i++) { 17273 TJoin join = stmt.getJoins().getJoin(i); 17274 ResultSet topResultSet = (ResultSet) modelManager.getModel(stmt); 17275 if (join.getJoinItems() != null && join.getJoinItems().size() > 0) { 17276 for (int k = 0; k < join.getJoinItems().size(); k++) { 17277 TTable table = join.getJoinItems().getJoinItem(k).getTable(); 17278 if (table != null && table.getSubquery() != null) { 17279 17280 ResultSet joinResultSet = (ResultSet) modelManager.getModel(table.getSubquery()); 17281 for (int x = 0; x < joinResultSet.getColumns().size(); x++) { 17282 ResultColumn sourceColumn = joinResultSet.getColumns().get(x); 17283 ResultColumn resultColumn = matchResultColumn(topResultSet.getColumns(), 17284 sourceColumn); 17285 if (resultColumn != null 17286 && resultColumn.getColumnObject() instanceof TResultColumn) { 17287 TResultColumn column = (TResultColumn) resultColumn.getColumnObject(); 17288 if (column.getAliasClause() == null && column.getFieldAttr() != null) { 17289 TObjectName resultObject = column.getFieldAttr(); 17290 if (resultObject.getSourceTable() == null 17291 || resultObject.getSourceTable().equals(table)) { 17292 DataFlowRelationship combinedQueryRelation = modelFactory 17293 .createDataFlowRelation(); 17294 combinedQueryRelation.setEffectType(EffectType.select); 17295 combinedQueryRelation 17296 .setTarget(new ResultColumnRelationshipElement(resultColumn)); 17297 combinedQueryRelation 17298 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 17299 } 17300 } 17301 } 17302 } 17303 } 17304 17305 if(join.getJoinItems().getJoinItem(k).getJoin()!=null) { 17306 analyzeJoin(join.getJoinItems().getJoinItem(k).getJoin(), EffectType.select); 17307 } 17308 } 17309 } 17310 analyzeJoin(join, EffectType.select); 17311 } 17312 } 17313 17314 if (stmt.getWhereClause() != null) { 17315 TExpression expr = stmt.getWhereClause().getCondition(); 17316 if (expr != null) { 17317 analyzeFilterCondition(null, expr, null, JoinClauseType.where, EffectType.select); 17318 } 17319 } 17320 17321 stmtStack.pop(); 17322 } 17323 } 17324 17325 protected TObjectNameList getTableLinkedColumns(TTable table) { 17326 if(structObjectMap.containsKey(table)) { 17327 return structObjectMap.get(table); 17328 } 17329 return table.getLinkedColumns(); 17330 } 17331 17332 protected boolean isTopResultSet(TSelectSqlStatement stmt) { 17333 TCustomSqlStatement parent = stmt.getParentStmt(); 17334 if (parent == null) 17335 return true; 17336 if (parent instanceof TMssqlReturn) { 17337 return true; 17338 } 17339 if (parent instanceof TReturnStmt) { 17340 return true; 17341 } 17342 if (parent instanceof TCommonBlock) { 17343 TCommonBlock block = (TCommonBlock) parent; 17344 if (block.getStatements() != null) { 17345 for (int i = 0; i < block.getStatements().size(); i++) { 17346 TCustomSqlStatement child = block.getStatements().get(i); 17347 if(stmt == child) { 17348 return true; 17349 } 17350 } 17351 } 17352 } 17353 if (parent instanceof TMssqlBlock) { 17354 TMssqlBlock block = (TMssqlBlock) parent; 17355 if (block.getStatements() != null) { 17356 for (int i = 0; i < block.getStatements().size(); i++) { 17357 TCustomSqlStatement child = block.getStatements().get(i); 17358 if(stmt == child) { 17359 return true; 17360 } 17361 } 17362 } 17363 } 17364 if (parent instanceof TStoredProcedureSqlStatement) { 17365 TStoredProcedureSqlStatement block = (TStoredProcedureSqlStatement) parent; 17366 if (block.getStatements() != null) { 17367 for (int i = 0; i < block.getStatements().size(); i++) { 17368 TCustomSqlStatement child = block.getStatements().get(i); 17369 if(child == stmt) { 17370 return true; 17371 } 17372 if (child instanceof TReturnStmt) { 17373 TReturnStmt returnStmt = (TReturnStmt) child; 17374 if (returnStmt.getStatements() != null) { 17375 for (int j = 0; j < returnStmt.getStatements().size(); j++) { 17376 TCustomSqlStatement child1 = returnStmt.getStatements().get(j); 17377 if(child1 == stmt) { 17378 return true; 17379 } 17380 } 17381 } 17382 } 17383 if (child instanceof TMssqlReturn) { 17384 TMssqlReturn returnStmt = (TMssqlReturn) child; 17385 if (returnStmt.getStatements() != null) { 17386 for (int j = 0; j < returnStmt.getStatements().size(); j++) { 17387 TCustomSqlStatement child1 = returnStmt.getStatements().get(j); 17388 if(child1 == stmt) { 17389 return true; 17390 } 17391 } 17392 } 17393 } 17394 } 17395 } 17396 } 17397 return false; 17398 } 17399 17400 protected void analyzeTableSubquery(TTable table) { 17401 if(table.getSubquery()!=null) { 17402 QueryTable queryTable = modelFactory.createQueryTable(table); 17403 TSelectSqlStatement subquery = table.getSubquery(); 17404 analyzeSelectStmt(subquery); 17405 17406 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 17407 17408 if (resultSetModel != null && resultSetModel != queryTable 17409 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 17410 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 17411 impactRelation.setEffectType(EffectType.select); 17412 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 17413 resultSetModel.getRelationRows())); 17414 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 17415 queryTable.getRelationRows())); 17416 } 17417 17418 if (resultSetModel != null && resultSetModel != queryTable 17419 && queryTable.getTableObject().getAliasClause() != null 17420 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 17421 for (int j = 0; j < queryTable.getColumns().size() 17422 && j < resultSetModel.getColumns().size(); j++) { 17423 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 17424 ResultColumn targetColumn = queryTable.getColumns().get(j); 17425 17426 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 17427 queryRalation.setEffectType(EffectType.select); 17428 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 17429 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 17430 } 17431 } else if (subquery.getSetOperatorType() != ESetOperatorType.none) { 17432 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 17433 .getModel(subquery); 17434 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 17435 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 17436 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 17437 sourceColumn); 17438 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 17439 targetColumn.bindStarLinkColumn(starLinkColumn); 17440 } 17441 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 17442 selectSetRalation.setEffectType(EffectType.select); 17443 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 17444 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 17445 } 17446 } 17447 } 17448 } 17449 17450 private ResultColumn getPivotedTableColumn(TPivotedTable pivotedTable, TObjectName columnName) { 17451 List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>(); 17452 if (pivotedTable.getPivotClause() != null) { 17453 pivotClauses.add(pivotedTable.getPivotClause()); 17454 } 17455 if (pivotedTable.getPivotClauseList() != null) { 17456 for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) { 17457 pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i)); 17458 } 17459 } 17460 for (TPivotClause clause : pivotClauses) { 17461 Object model = modelManager.getModel(clause); 17462 if (model instanceof PivotedTable) { 17463 PivotedTable pivotedTableModel = (PivotedTable) model; 17464 if (pivotedTableModel.getColumns() != null) { 17465 for (ResultColumn column : pivotedTableModel.getColumns()) { 17466 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 17467 getColumnName(SQLUtil.trimColumnStringQuote(column.getName())))) { 17468 return column; 17469 } 17470 } 17471 } 17472 } 17473 } 17474 return null; 17475 } 17476 17477 private void analyzeHiveTransformClause(TSelectSqlStatement stmt, THiveTransformClause transformClause) { 17478 Table mapSourceTable = null; 17479 QueryTable mapQueryTable = null; 17480 if(stmt.getTables()!=null) { 17481 for(int i=0;i<stmt.getTables().size();i++) { 17482 TTable table = stmt.getTables().getTable(i); 17483 if (table.getSubquery() != null) { 17484 if (transformClause.getTransformType() == ETransformType.ettReduce) { 17485 mapQueryTable = modelFactory.createQueryTable(table); 17486 } 17487 analyzeSelectStmt(table.getSubquery()); 17488 } 17489 else { 17490 mapSourceTable = modelFactory.createTable(table); 17491 } 17492 } 17493 } 17494 17495 if (transformClause.getTransformType() == ETransformType.ettReduce) { 17496 modelFactory.createResultSet(stmt, false); 17497 } 17498 17499 List<TableColumn> mapTableColumns = new ArrayList<TableColumn>(); 17500 List<ResultColumn> mapResultSetColumns = new ArrayList<ResultColumn>(); 17501 List<ResultColumn> redueResultSetColumns = new ArrayList<ResultColumn>(); 17502 17503 if(transformClause.getExpressionList()!=null) { 17504 for(TExpression expression: transformClause.getExpressionList()) { 17505 if(expression.getObjectOperand()!=null) { 17506 if (transformClause.getTransformType() == ETransformType.ettMap || transformClause.getTransformType() == ETransformType.ettSelect) { 17507 if (mapSourceTable != null) { 17508 TableColumn tableColumn = modelFactory.createTableColumn(mapSourceTable, 17509 expression.getObjectOperand(), false); 17510 if (tableColumn != null) { 17511 mapTableColumns.add(tableColumn); 17512 } 17513 } 17514 } 17515 else if (transformClause.getTransformType() == ETransformType.ettReduce) { 17516 if (mapQueryTable != null) { 17517 ResultColumn resultColumn = modelFactory.createResultColumn(mapQueryTable, 17518 expression.getObjectOperand(), false); 17519 if (resultColumn != null) { 17520 mapResultSetColumns.add(resultColumn); 17521 } 17522 } 17523 } 17524 } 17525 } 17526 } 17527 17528 if (transformClause.getAliasClause() != null) { 17529 Object model = modelManager.getModel(stmt); 17530 if (model instanceof ResultSet) { 17531 ResultSet result = (ResultSet) model; 17532 if (result!=null && transformClause.getAliasClause().getColumns() != null) { 17533 for (TObjectName column : transformClause.getAliasClause().getColumns()) { 17534 ResultColumn resultColumn = modelFactory.createResultColumn(result, column); 17535 if (resultColumn != null) { 17536 if (transformClause.getTransformType() == ETransformType.ettMap 17537 || transformClause.getTransformType() == ETransformType.ettSelect) { 17538 mapResultSetColumns.add(resultColumn); 17539 } 17540 else if (transformClause.getTransformType() == ETransformType.ettReduce) { 17541 redueResultSetColumns.add(resultColumn); 17542 } 17543 } 17544 } 17545 } 17546 } 17547 } 17548 17549 if (transformClause.getTransformType() == ETransformType.ettMap 17550 || transformClause.getTransformType() == ETransformType.ettSelect) { 17551 if (!mapTableColumns.isEmpty() && !mapResultSetColumns.isEmpty()) { 17552 for (ResultColumn resultColumn : mapResultSetColumns) { 17553 for (TableColumn tableColumn : mapTableColumns) { 17554 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17555 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17556 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 17557 relation.setEffectType(EffectType.select); 17558 } 17559 } 17560 } 17561 } 17562 else if (transformClause.getTransformType() == ETransformType.ettReduce) { 17563 if (!redueResultSetColumns.isEmpty() && !mapResultSetColumns.isEmpty()) { 17564 for (ResultColumn reduceResultColumn : redueResultSetColumns) { 17565 for (ResultColumn mapResultColumn : mapResultSetColumns) { 17566 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17567 relation.setTarget(new ResultColumnRelationshipElement(reduceResultColumn)); 17568 relation.addSource(new ResultColumnRelationshipElement(mapResultColumn)); 17569 relation.setEffectType(EffectType.select); 17570 } 17571 } 17572 } 17573 } 17574 } 17575 17576 protected boolean isStructColumn(TObjectName columnName) { 17577 return columnName.getSourceTable() != null && columnName.getSourceTable().getAliasClause() != null 17578 && columnName.getSourceTable().getUnnestClause() != null 17579 && DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 17580 getColumnName(columnName.getSourceTable().getAliasClause().getAliasName())); 17581 } 17582 17583 private TObjectName getObjectName(ResultColumn column) { 17584 if (column.getColumnObject() instanceof TResultColumn) { 17585 TResultColumn resultColumn = (TResultColumn) column.getColumnObject(); 17586 if (resultColumn.getAliasClause() != null && resultColumn.getAliasClause().getAliasName() != null) { 17587 return resultColumn.getAliasClause().getAliasName(); 17588 } 17589 if (resultColumn.getFieldAttr() != null) { 17590 return resultColumn.getFieldAttr(); 17591 } 17592 if (resultColumn.getExpr() != null 17593 && resultColumn.getExpr().getExpressionType() == EExpressionType.simple_object_name_t) { 17594 return resultColumn.getExpr().getObjectOperand(); 17595 } 17596 } else if (column.getColumnObject() instanceof TObjectName) { 17597 return (TObjectName) column.getColumnObject(); 17598 } 17599 return null; 17600 } 17601 17602 private boolean isShowTopSelectResultSet() { 17603 if (option.isSimpleOutput() && !option.isSimpleShowTopSelectResultSet()) 17604 return false; 17605 return true; 17606 } 17607 17608 private void analyzeSelectIntoClause(TSelectSqlStatement stmt) { 17609 if (stmt.getParentStmt() instanceof TSelectSqlStatement) { 17610 return; 17611 } 17612 17613 TableColumn oracleIntoTableColumn = null; 17614 17615 TIntoClause intoClause = stmt.getIntoClause(); 17616 17617 TSelectSqlStatement leftStmt = DlineageUtil.getLeftStmt(stmt); 17618 17619 if (intoClause == null && leftStmt != null) { 17620 intoClause = leftStmt.getIntoClause(); 17621 } 17622 17623 if (intoClause != null) { 17624 List<TObjectName> tableNames = new ArrayList<TObjectName>(); 17625 if (intoClause.getExprList() != null) { 17626 for (int j = 0; j < intoClause.getExprList().size(); j++) { 17627 TObjectName tableName = intoClause.getExprList().getExpression(j).getObjectOperand(); 17628 if (tableName != null) { 17629 if (tableName.toString().startsWith(":") && option.getVendor() == EDbVendor.dbvoracle 17630 && tableName.getDbObjectType() == EDbObjectType.column) { 17631 TObjectName tableAlias = new TObjectName(); 17632 tableAlias.setString(tableName.getTableString()); 17633 tableNames.add(tableAlias); 17634 TTable sourceTable = tableName.getSourceTable(); 17635 Table sourceTableModel = modelFactory.createTable(sourceTable, tableAlias); 17636 oracleIntoTableColumn = modelFactory.createTableColumn(sourceTableModel, tableName, true); 17637 } else { 17638 if (tableName != null) { 17639 tableNames.add(tableName); 17640 } 17641 } 17642 } 17643 else if(intoClause.getExprList().getExpression(j).getFunctionCall()!=null) { 17644 TObjectName variableName = intoClause.getExprList().getExpression(j).getFunctionCall().getFunctionName(); 17645 tableNames.add(variableName); 17646 Variable variable = modelFactory.createVariable(variableName); 17647 variable.setSubType(SubType.record); 17648 TObjectName variableProperties = new TObjectName(); 17649 variableProperties.setString("*"); 17650 modelFactory.createTableColumn(variable, variableProperties, true); 17651 } 17652 } 17653 } else if (intoClause.getVariableList() != null) { 17654 for (int j = 0; j < intoClause.getVariableList().size(); j++) { 17655 TObjectName tableName = intoClause.getVariableList().getObjectName(j); 17656 if (tableName != null) { 17657 tableNames.add(tableName); 17658 } 17659 } 17660 } else if (intoClause.getIntoName() != null) { 17661 tableNames.add(intoClause.getIntoName()); 17662 } 17663 17664 ResultSet queryModel = (ResultSet) modelManager.getModel(stmt.getResultColumnList()); 17665 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 17666 queryModel = (ResultSet) modelManager.getModel(stmt); 17667 } 17668 for (int j = 0; j < tableNames.size(); j++) { 17669 TObjectName tableName = tableNames.get(j); 17670 if (tableName.getColumnNameOnly().startsWith("@") 17671 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 17672 continue; 17673 } 17674 17675 if (tableName.getColumnNameOnly().startsWith(":") 17676 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 17677 continue; 17678 } 17679 17680 Table tableModel; 17681 TableColumn variableColumn = null; 17682 17683 if (tableName.getDbObjectType() == EDbObjectType.variable) { 17684 if (tableName.toString().indexOf(".") != -1) { 17685 List<String> splits = SQLUtil.parseNames(tableName.toString()); 17686 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 17687 } else { 17688 tableModel = modelFactory.createVariable(tableName); 17689 } 17690 if (tableModel.getSubType() == null) { 17691 tableModel.setSubType(SubType.record); 17692 } 17693 if(tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 17694 TObjectName variableProperties = new TObjectName(); 17695 variableProperties.setString("*"); 17696 variableColumn = modelFactory.createTableColumn(tableModel, variableProperties, true); 17697 } 17698 } else { 17699 tableModel = modelFactory.createTableByName(tableName); 17700 } 17701 17702 if (queryModel instanceof ResultSet && (stmt.getWhereClause() != null || hasJoin(stmt))) { 17703 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 17704 impactRelation.setEffectType(EffectType.insert); 17705 impactRelation.addSource( 17706 new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)queryModel).getRelationRows())); 17707 impactRelation.setTarget( 17708 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 17709 } 17710 17711 Process process = modelFactory.createProcess(stmt); 17712 tableModel.addProcess(process); 17713 17714 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 17715 for (ResultColumn resultColumn : queryModel.getColumns()) { 17716 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 17717 resultColumn.getName()); 17718 17719 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 17720 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 17721 TSQLSchema schema = sqlenv 17722 .getSQLSchema(tableModel.getDatabase() + "." + tableModel.getSchema(), true); 17723 if (schema != null) { 17724 TSQLTable tempTable = schema 17725 .createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 17726 tempTable.addColumn(tableColumn.getName()); 17727 } 17728 } 17729 17730 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17731 relation.setEffectType(EffectType.insert); 17732 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17733 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17734 relation.setProcess(process); 17735 } 17736 17737 tableModel.setDetermined(queryModel.isDetermined()); 17738 if(queryModel.isDetermined() && DlineageUtil.isTempTable(tableModel, option.getVendor())) { 17739 tableModel.setCreateTable(true, false); 17740 } 17741 return; 17742 } 17743 17744 boolean isDetermined = true; 17745 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 17746 if (tableNames.size() > 1 && tableName.getDbObjectType() == EDbObjectType.variable) { 17747 if (i != j) { 17748 continue; 17749 } 17750 } 17751 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 17752 17753 if ("*".equals(column.getColumnNameOnly()) && column.getFieldAttr() != null 17754 && column.getFieldAttr().getSourceTable() != null) { 17755 Object model = modelManager.getModel(column); 17756 if(model instanceof LinkedHashMap) { 17757 LinkedHashMap<String, ResultColumn> columns = (LinkedHashMap<String, ResultColumn>)model; 17758 for(String key: columns.keySet()) { 17759 ResultColumn sourceColumn = columns.get(key); 17760 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 17761 sourceColumn.getName()); 17762 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17763 relation.setEffectType(EffectType.insert); 17764 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17765 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 17766 relation.setProcess(process); 17767 } 17768 } 17769 else if(model instanceof ResultColumn) { 17770 isDetermined = false; 17771 ResultColumn resultColumn = (ResultColumn) model; 17772 List<TObjectName> columns = resultColumn.getStarLinkColumnList(); 17773 if (columns.size() > 0) { 17774 for (int k = 0; k < columns.size(); k++) { 17775 17776 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 17777 columns.get(k)); 17778 17779 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 17780 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 17781 TSQLSchema schema = sqlenv.getSQLSchema( 17782 tableModel.getDatabase() + "." + tableModel.getSchema(), true); 17783 if (schema != null) { 17784 TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 17785 tempTable.addColumn(tableColumn.getName()); 17786 } 17787 } 17788 17789 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17790 relation.setEffectType(EffectType.insert); 17791 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17792 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17793 relation.setProcess(process); 17794 } 17795 if (resultColumn.isShowStar()) { 17796 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 17797 column.getFieldAttr()); 17798 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17799 relation.setEffectType(EffectType.insert); 17800 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17801 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17802 relation.setProcess(process); 17803 } 17804 } else { 17805 TObjectName columnObject = column.getFieldAttr(); 17806 if (column.getAliasClause() != null) { 17807 columnObject = column.getAliasClause().getAliasName(); 17808 } 17809 if (columnObject != null) { 17810 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 17811 columnObject); 17812 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17813 relation.setEffectType(EffectType.insert); 17814 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17815 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17816 relation.setProcess(process); 17817 } else if (!SQLUtil.isEmpty(column.getColumnAlias())) { 17818 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 17819 column.getAliasClause().getAliasName()); 17820 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17821 relation.setEffectType(EffectType.insert); 17822 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17823 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17824 relation.setProcess(process); 17825 } 17826 } 17827 } 17828 } else { 17829 ResultColumn resultColumn = null; 17830 17831 if (queryModel instanceof QueryTable) { 17832 resultColumn = (ResultColumn) modelManager.getModel(column); 17833 } else if (queryModel instanceof ResultSet) { 17834 resultColumn = (ResultColumn) modelManager.getModel(column); 17835 } else { 17836 continue; 17837 } 17838 17839 if (resultColumn == null && column.getAliasClause() != null) { 17840 resultColumn = (ResultColumn) modelManager.getModel(column.getAliasClause().getAliasName()); 17841 } 17842 17843 if (resultColumn != null) { 17844 TObjectName columnObject = column.getFieldAttr(); 17845 if (column.getAliasClause() != null) { 17846 columnObject = column.getAliasClause().getAliasName(); 17847 } 17848 TableColumn tableColumn = null; 17849 if (columnObject != null) { 17850 if (tableModel.isVariable()) { 17851 if (variableColumn != null) { 17852 tableColumn = variableColumn; 17853 } else { 17854 tableColumn = tableModel.getColumns().get(0); 17855 } 17856 } 17857 else if (oracleIntoTableColumn != null) { 17858 tableColumn = oracleIntoTableColumn; 17859 } 17860 else { 17861 tableColumn = modelFactory.createInsertTableColumn(tableModel, columnObject); 17862 if (containStarColumn(queryModel)) { 17863 tableColumn.notBindStarLinkColumn(true); 17864 } 17865 } 17866 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17867 relation.setEffectType(EffectType.insert); 17868 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17869 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17870 relation.setProcess(process); 17871 } else if (!SQLUtil.isEmpty(column.getColumnAlias())) { 17872 if (tableModel.isVariable()) { 17873 if (variableColumn != null) { 17874 tableColumn = variableColumn; 17875 } else { 17876 tableColumn = tableModel.getColumns().get(0); 17877 } 17878 } else { 17879 tableColumn = modelFactory.createInsertTableColumn(tableModel, 17880 column.getAliasClause().getAliasName()); 17881 } 17882 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17883 relation.setEffectType(EffectType.insert); 17884 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17885 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17886 relation.setProcess(process); 17887 } else { 17888 if (tableModel.isVariable()) { 17889 if (variableColumn != null) { 17890 tableColumn = variableColumn; 17891 } else { 17892 tableColumn = tableModel.getColumns().get(0); 17893 } 17894 } 17895 if (tableColumn != null) { 17896 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17897 relation.setEffectType(EffectType.insert); 17898 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 17899 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 17900 relation.setProcess(process); 17901 } 17902 } 17903 } 17904 } 17905 } 17906 tableModel.setDetermined(isDetermined); 17907 if(isDetermined && DlineageUtil.isTempTable(tableModel, option.getVendor())) { 17908 tableModel.setCreateTable(true, false); 17909 } 17910 } 17911 } 17912 } 17913 17914 private boolean isUnPivotedTable(TPivotedTable pivotedTable) { 17915 if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) { 17916 return pivotedTable.getPivotClauseList().getElement(0).getType() == TPivotClause.unpivot; 17917 } else { 17918 TPivotClause pivotClause = pivotedTable.getPivotClause(); 17919 return pivotClause.getType() == TPivotClause.unpivot; 17920 } 17921 } 17922 17923 private void analyzeUnPivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) { 17924 List<Object> tables = new ArrayList<Object>(); 17925 Set<Object> pivotedColumns = new HashSet<Object>(); 17926 TTable fromTable = pivotedTable.getTableSource(); 17927 Object table = modelManager.getModel(fromTable); 17928 List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>(); 17929 if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) { 17930 for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) { 17931 pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i)); 17932 } 17933 } else { 17934 TPivotClause pivotClause = pivotedTable.getPivotClause(); 17935 pivotClauses.add(pivotClause); 17936 } 17937 17938 for (int y = 0; y < pivotClauses.size(); y++) { 17939 TPivotClause pivotClause = pivotClauses.get(y); 17940 PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause); 17941 pivotTable.setUnpivoted(true); 17942 17943 if (pivotClause.getValueColumnList() != null) { 17944 for (int j = 0; j < pivotClause.getValueColumnList().size(); j++) { 17945 modelFactory.createResultColumn(pivotTable, pivotClause.getValueColumnList().getObjectName(j)); 17946 } 17947 } 17948 if (pivotClause.getPivotColumnList() != null) { 17949 for (int j = 0; j < pivotClause.getPivotColumnList().size(); j++) { 17950 modelFactory.createResultColumn(pivotTable, pivotClause.getPivotColumnList().getObjectName(j)); 17951 } 17952 } 17953 if (pivotClause.getUnpivotInClause()!=null && pivotClause.getUnpivotInClause().getItems() != null) { 17954 for (int j = 0; j < pivotClause.getUnpivotInClause().getItems().size(); j++) { 17955 TObjectName columnName = pivotClause.getUnpivotInClause().getItems().getElement(j).getColumn(); 17956 if (columnName != null) { 17957 if (table instanceof QueryTable) { 17958 for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) { 17959 if (getColumnName(columnName) 17960 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 17961 for (ResultColumn resultColumn : pivotTable.getColumns()) { 17962 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17963 relation.setEffectType(EffectType.select); 17964 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17965 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17966 pivotedColumns.add(tableColumn); 17967 } 17968 break; 17969 } 17970 } 17971 } else if (table instanceof Table) { 17972 for (TableColumn tableColumn : ((Table) table).getColumns()) { 17973 if (getColumnName(columnName) 17974 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 17975 for (ResultColumn resultColumn : pivotTable.getColumns()) { 17976 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17977 relation.setEffectType(EffectType.select); 17978 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17979 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 17980 pivotedColumns.add(tableColumn); 17981 } 17982 break; 17983 } 17984 } 17985 } 17986 } else { 17987 TObjectNameList columnNames = pivotClause.getUnpivotInClause().getItems().getElement(j) 17988 .getColumnList(); 17989 for (TObjectName columnName1 : columnNames) { 17990 if (table instanceof QueryTable) { 17991 for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) { 17992 if (getColumnName(columnName1).equals( 17993 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 17994 for (ResultColumn resultColumn : pivotTable.getColumns()) { 17995 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17996 relation.setEffectType(EffectType.select); 17997 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17998 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17999 pivotedColumns.add(tableColumn); 18000 } 18001 break; 18002 } 18003 } 18004 } else if (table instanceof Table) { 18005 for (TableColumn tableColumn : ((Table) table).getColumns()) { 18006 if (getColumnName(columnName1).equals( 18007 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18008 for (ResultColumn resultColumn : pivotTable.getColumns()) { 18009 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18010 relation.setEffectType(EffectType.select); 18011 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18012 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18013 pivotedColumns.add(tableColumn); 18014 } 18015 break; 18016 } 18017 } 18018 } 18019 } 18020 } 18021 } 18022 } 18023 tables.add(pivotTable); 18024 tables.add(table); 18025 } 18026 18027 ResultSet resultSet = modelFactory.createResultSet(stmt, 18028 isTopResultSet(stmt) && isShowTopSelectResultSet()); 18029 TResultColumnList columnList = stmt.getResultColumnList(); 18030 for (int i = 0; i < columnList.size(); i++) { 18031 TResultColumn column = columnList.getResultColumn(i); 18032 ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i); 18033 if (resultColumn.getColumnObject() instanceof TResultColumn) { 18034 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 18035 if (columnObject.getFieldAttr() != null) { 18036 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 18037 resultColumn.setShowStar(false); 18038 int index = 0; 18039 for (int k = 0; k < tables.size(); k++) { 18040 Object tableItem = tables.get(k); 18041 if (tableItem instanceof ResultSet) { 18042 for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) { 18043 ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x); 18044 if (pivotedColumns.contains(tableColumn)) { 18045 continue; 18046 } 18047 if (tableColumn.getColumnObject() instanceof TObjectName) { 18048 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject()); 18049 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18050 relation.setEffectType(EffectType.select); 18051 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 18052 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18053 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 18054 if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) { 18055 if (tableColumn.hasStarLinkColumn()) { 18056 for (int z = 0; z < tableColumn.getStarLinkColumnList().size(); z++) { 18057 ResultColumn resultColumn1 = modelFactory.createResultColumn( 18058 (ResultSet) tableItem, 18059 tableColumn.getStarLinkColumnList().get(z)); 18060 DataFlowRelationship relation = modelFactory 18061 .createDataFlowRelation(); 18062 relation.setEffectType(EffectType.select); 18063 relation.setTarget( 18064 new ResultColumnRelationshipElement(resultColumn)); 18065 relation.addSource( 18066 new ResultColumnRelationshipElement(resultColumn1)); 18067 tableColumn.getStarLinkColumns().remove( 18068 getColumnName(tableColumn.getStarLinkColumnList().get(z))); 18069 z--; 18070 } 18071 } else { 18072 resultColumn.bindStarLinkColumn( 18073 ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr()); 18074 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18075 relation.setEffectType(EffectType.select); 18076 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr())); 18077 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18078 } 18079 } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) { 18080 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()) 18081 .getExpr(); 18082 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 18083 TObjectName columnName = new TObjectName(); 18084 columnName.setString(expr.toString()); 18085 resultColumn.bindStarLinkColumn(columnName); 18086 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18087 relation.setEffectType(EffectType.select); 18088 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, columnName)); 18089 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18090 } 18091 } 18092 } 18093 } 18094 } else if (tableItem instanceof Table) { 18095 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18096 if (pivotedColumns.contains(tableColumn)) { 18097 continue; 18098 } 18099 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(), index); 18100 index++; 18101 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18102 relation.setEffectType(EffectType.select); 18103 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 18104 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18105 } 18106 } 18107 } 18108 } else { 18109 for (int k = 0; k < tables.size(); k++) { 18110 Object tableItem = tables.get(k); 18111 if (tableItem instanceof ResultSet) { 18112 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 18113 if (getColumnName(columnObject.getFieldAttr()).equals( 18114 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18115 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18116 relation.setEffectType(EffectType.select); 18117 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18118 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18119 break; 18120 } 18121 } 18122 } else if (tableItem instanceof Table) { 18123 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18124 if (getColumnName(columnObject.getFieldAttr()).equals( 18125 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18126 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18127 relation.setEffectType(EffectType.select); 18128 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18129 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18130 break; 18131 } 18132 } 18133 } 18134 } 18135 } 18136 } else if (columnObject.getExpr() != null) { 18137 analyzeResultColumn(column, EffectType.select); 18138 } 18139 } 18140 } 18141 } 18142 18143 private void analyzePivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) { 18144 List<Object> tables = new ArrayList<Object>(); 18145 Set<Object> pivotedColumns = new HashSet<Object>(); 18146 TTable fromTable = pivotedTable.getTableSource(); 18147 Object table = modelManager.getModel(fromTable); 18148 if(table == null && fromTable.getSubquery()!=null) { 18149 table = modelFactory.createQueryTable(fromTable); 18150 TSelectSqlStatement subquery = fromTable.getSubquery(); 18151 analyzeSelectStmt(subquery); 18152 } 18153 List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>(); 18154 if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) { 18155 for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) { 18156 pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i)); 18157 } 18158 } else { 18159 TPivotClause pivotClause = pivotedTable.getPivotClause(); 18160 pivotClauses.add(pivotClause); 18161 } 18162 18163 for (int y = 0; y < pivotClauses.size(); y++) { 18164 TPivotClause pivotClause = pivotClauses.get(y); 18165 List<TFunctionCall> functionCalls = new ArrayList<TFunctionCall>(); 18166 if (pivotClause.getAggregation_function() != null || pivotClause.getAggregation_function_list() != null) { 18167 if (pivotClause.getAggregation_function() != null) { 18168 functionCalls.add((TFunctionCall) pivotClause.getAggregation_function()); 18169 } else if (pivotClause.getAggregation_function_list() != null) { 18170 for (int i = 0; i < pivotClause.getAggregation_function_list().size(); i++) { 18171 functionCalls.add((TFunctionCall) pivotClause.getAggregation_function_list().getResultColumn(i) 18172 .getExpr().getFunctionCall()); 18173 } 18174 } 18175 18176 if (functionCalls.isEmpty()) { 18177 return; 18178 } 18179 18180 if (pivotClause.getPivotColumnList() == null) { 18181 return; 18182 } 18183 18184 if (pivotClause.getPivotInClause() == null) { 18185 return; 18186 } 18187 18188 for (int x = 0; x < functionCalls.size(); x++) { 18189 TFunctionCall functionCall = functionCalls.get(x); 18190 Function function = modelFactory.createFunction(functionCall); 18191 ResultColumn column = modelFactory.createFunctionResultColumn(function, 18192 ((TFunctionCall) functionCall).getFunctionName()); 18193 18194 List<TExpression> expressions = new ArrayList<TExpression>(); 18195 getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall); 18196 18197 for (int j = 0; j < expressions.size(); j++) { 18198 columnsInExpr visitor = new columnsInExpr(); 18199 expressions.get(j).inOrderTraverse(visitor); 18200 List<TObjectName> objectNames = visitor.getObjectNames(); 18201 if (objectNames == null) { 18202 continue; 18203 } 18204 for (TObjectName columnName : objectNames) { 18205 if (table instanceof QueryTable) { 18206 for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) { 18207 boolean find = false; 18208 ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i); 18209 if (tableColumn.hasStarLinkColumn()) { 18210 for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) { 18211 TObjectName objectName = tableColumn.getStarLinkColumnList().get(k); 18212 if (getColumnName(columnName).equals(getColumnName(objectName))) { 18213 ResultColumn resultColumn = modelFactory 18214 .createResultColumn((QueryTable) table, objectName); 18215 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18216 relation.setEffectType(EffectType.select); 18217 relation.setTarget(new ResultColumnRelationshipElement(column)); 18218 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18219 pivotedColumns.add(resultColumn); 18220 tableColumn.getStarLinkColumns() 18221 .remove(DlineageUtil.getColumnName(objectName)); 18222 find = true; 18223 break; 18224 } 18225 } 18226 } else if (getColumnName(columnName).equals( 18227 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18228 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18229 relation.setEffectType(EffectType.select); 18230 relation.setTarget(new ResultColumnRelationshipElement(column)); 18231 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18232 pivotedColumns.add(tableColumn); 18233 find = true; 18234 break; 18235 } 18236 18237 if (!find && tableColumn.getName().endsWith("*")) { 18238 QueryTable queryTable = (QueryTable)table; 18239 ResultColumn resultColumn = modelFactory.createResultColumn(queryTable, columnName); 18240 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18241 relation.setEffectType(EffectType.select); 18242 relation.setTarget(new ResultColumnRelationshipElement(column)); 18243 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18244 tableColumn.bindStarLinkColumn(columnName); 18245 } 18246 } 18247 } else if (table instanceof Table) { 18248 for (TableColumn tableColumn : ((Table) table).getColumns()) { 18249 if (getColumnName(columnName).equals( 18250 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18251 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18252 relation.setEffectType(EffectType.select); 18253 relation.setTarget(new ResultColumnRelationshipElement(column)); 18254 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18255 pivotedColumns.add(tableColumn); 18256 break; 18257 } 18258 } 18259 } 18260 } 18261 } 18262 18263 PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause); 18264 pivotTable.setUnpivoted(false); 18265 18266 if (pivotClause.getPivotInClause().getItems() != null) { 18267 for (int j = 0; j < pivotClause.getPivotInClause().getItems().size(); j++) { 18268 ResultColumn resultColumn = null; 18269 if (pivotClause.getAggregation_function_list() != null 18270 && pivotClause.getAggregation_function_list().size() > 1) { 18271 TResultColumn functionColumn = pivotClause.getAggregation_function_list() 18272 .getResultColumn(x); 18273 TObjectName tableColumn = new TObjectName(); 18274 if (option.getVendor() == EDbVendor.dbvbigquery) { 18275 tableColumn.setString(getResultColumnString(functionColumn) + "_" 18276 + SQLUtil.trimColumnStringQuote(getResultColumnString( 18277 pivotClause.getPivotInClause().getItems().getResultColumn(j)))); 18278 } 18279 else { 18280 tableColumn.setString(SQLUtil 18281 .trimColumnStringQuote(getResultColumnString( 18282 pivotClause.getPivotInClause().getItems().getResultColumn(j))) 18283 + "_" + getResultColumnString(functionColumn)); 18284 } 18285 resultColumn = modelFactory.createResultColumn(pivotTable, tableColumn); 18286 } else { 18287 resultColumn = modelFactory.createSelectSetResultColumn(pivotTable, 18288 pivotClause.getPivotInClause().getItems().getResultColumn(j), j); 18289 } 18290 { 18291 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18292 relation.setEffectType(EffectType.select); 18293 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18294 relation.addSource(new ResultColumnRelationshipElement(column)); 18295 } 18296 { 18297 for (TObjectName columnName : pivotClause.getPivotColumnList()) { 18298 if (table instanceof QueryTable) { 18299 for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) { 18300 ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i); 18301 if (tableColumn.hasStarLinkColumn()) { 18302 for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) { 18303 TObjectName objectName = tableColumn.getStarLinkColumnList().get(k); 18304 if (getColumnName(columnName).equals(getColumnName(objectName))) { 18305 ResultColumn resultColumn1 = modelFactory 18306 .createResultColumn((QueryTable) table, objectName); 18307 DataFlowRelationship relation = modelFactory 18308 .createDataFlowRelation(); 18309 relation.setEffectType(EffectType.select); 18310 relation.setTarget(new ResultColumnRelationshipElement(column)); 18311 relation.addSource( 18312 new ResultColumnRelationshipElement(resultColumn1)); 18313 pivotedColumns.add(resultColumn1); 18314 tableColumn.getStarLinkColumns() 18315 .remove(DlineageUtil.getColumnName(objectName)); 18316 break; 18317 } 18318 } 18319 } else if (getColumnName(columnName).equals(DlineageUtil 18320 .getIdentifierNormalColumnName(tableColumn.getName()))) { 18321 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18322 relation.setEffectType(EffectType.select); 18323 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18324 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18325 pivotedColumns.add(tableColumn); 18326 break; 18327 } 18328 } 18329 } else if (table instanceof Table) { 18330 for (TableColumn tableColumn : ((Table) table).getColumns()) { 18331 if (getColumnName(columnName).equals(DlineageUtil 18332 .getIdentifierNormalColumnName(tableColumn.getName()))) { 18333 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18334 relation.setEffectType(EffectType.select); 18335 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18336 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18337 pivotedColumns.add(tableColumn); 18338 break; 18339 } 18340 } 18341 } 18342 } 18343 } 18344 } 18345 } else if (pivotClause.getPivotInClause().getSubQuery() != null) { 18346 TSelectSqlStatement subquery = pivotClause.getPivotInClause().getSubQuery(); 18347 analyzeSelectStmt(subquery); 18348 ResultSet selectSetResultSetModel = (ResultSet) modelManager.getModel(subquery); 18349 for (int j = 0; j < subquery.getResultColumnList().size(); j++) { 18350 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(pivotTable, 18351 subquery.getResultColumnList().getResultColumn(j), j); 18352 { 18353 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18354 relation.setEffectType(EffectType.select); 18355 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18356 relation.addSource(new ResultColumnRelationshipElement(column)); 18357 relation.addSource(new ResultColumnRelationshipElement( 18358 selectSetResultSetModel.getColumns().get(j))); 18359 } 18360 { 18361 for (TObjectName columnName : pivotClause.getPivotColumnList()) { 18362 if (table instanceof QueryTable) { 18363 for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) { 18364 if (getColumnName(columnName).equals(DlineageUtil 18365 .getIdentifierNormalColumnName(tableColumn.getName()))) { 18366 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18367 relation.setEffectType(EffectType.select); 18368 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18369 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18370 pivotedColumns.add(tableColumn); 18371 break; 18372 } 18373 } 18374 } else if (table instanceof Table) { 18375 for (TableColumn tableColumn : ((Table) table).getColumns()) { 18376 if (getColumnName(columnName).equals(DlineageUtil 18377 .getIdentifierNormalColumnName(tableColumn.getName()))) { 18378 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18379 relation.setEffectType(EffectType.select); 18380 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18381 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18382 pivotedColumns.add(tableColumn); 18383 break; 18384 } 18385 } 18386 } 18387 } 18388 } 18389 } 18390 } 18391 tables.add(pivotTable); 18392 tables.add(table); 18393 } 18394 } 18395 } 18396 18397 TPivotClause pivotClause = pivotClauses.get(0); 18398 boolean hasAlias = pivotClause.getAliasClause() != null && pivotClause.getAliasClause().getColumns() != null 18399 && pivotClause.getAliasClause().getColumns().size() > 0; 18400 if (hasAlias) { 18401 Alias alias = modelFactory.createAlias(pivotClause.getAliasClause()); 18402 List<TObjectName> aliasColumns = new ArrayList<TObjectName>(); 18403 int index = 0; 18404 for (int k = 0; k < tables.size(); k++) { 18405 Object tableItem = tables.get(k); 18406 if (tableItem instanceof ResultSet) { 18407 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 18408 if (pivotedColumns.contains(tableColumn)) { 18409 continue; 18410 } 18411 if (tableColumn.getColumnObject() instanceof TObjectName) { 18412 aliasColumns.add((TObjectName) tableColumn.getColumnObject()); 18413 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 18414 if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) { 18415 aliasColumns.add(((TResultColumn) tableColumn.getColumnObject()).getFieldAttr()); 18416 } else { 18417 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr(); 18418 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 18419 TObjectName columnName = new TObjectName(); 18420 columnName.setString(expr.toString()); 18421 aliasColumns.add(columnName); 18422 } 18423 } 18424 } 18425 } 18426 } else if (tableItem instanceof Table) { 18427 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18428 if (pivotedColumns.contains(tableColumn)) { 18429 continue; 18430 } 18431 aliasColumns.add(index, (TObjectName) tableColumn.getColumnObject()); 18432 index++; 18433 } 18434 } 18435 } 18436 18437 IndexedLinkedHashMap<String, ResultColumn> aliasColumnMap = new IndexedLinkedHashMap<String, ResultColumn>(); 18438 int diffCount = pivotClause.getAliasClause().getColumns().size() - aliasColumns.size(); 18439 for (int k = 0; k < pivotClause.getAliasClause().getColumns().size(); k++) { 18440 if (pivotClause.getAliasClause().getColumns().size() > aliasColumns.size()) { 18441 if (k < diffCount) { 18442 continue; 18443 } 18444 ResultColumn resultColumn = modelFactory.createResultColumn(alias, 18445 pivotClause.getAliasClause().getColumns().getObjectName(k)); 18446 if ((k - diffCount) < aliasColumns.size()) { 18447 aliasColumnMap.put(aliasColumns.get(k - diffCount).toString(), resultColumn); 18448 } 18449 } else { 18450 ResultColumn resultColumn = modelFactory.createResultColumn(alias, 18451 pivotClause.getAliasClause().getColumns().getObjectName(k)); 18452 if (k < aliasColumns.size()) { 18453 aliasColumnMap.put(aliasColumns.get(k).toString(), resultColumn); 18454 } 18455 } 18456 } 18457 18458 for (int k = 0; k < tables.size(); k++) { 18459 Object tableItem = tables.get(k); 18460 if (tableItem instanceof ResultSet) { 18461 int resultColumnSize = ((ResultSet) tableItem).getColumns().size(); 18462 for (int x = 0; x < resultColumnSize; x++) { 18463 ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x); 18464 if (pivotedColumns.contains(tableColumn)) { 18465 continue; 18466 } 18467 if (tableColumn.getColumnObject() instanceof TObjectName) { 18468 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18469 relation.setEffectType(EffectType.select); 18470 relation.setTarget(new ResultColumnRelationshipElement( 18471 aliasColumnMap.get(tableColumn.getColumnObject().toString()))); 18472 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18473 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 18474 if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) { 18475 ResultColumn targetColumn = aliasColumnMap.get( 18476 ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr().toString()); 18477 if(targetColumn == null) { 18478 continue; 18479 } 18480 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18481 relation.setEffectType(EffectType.select); 18482 relation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 18483 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18484 } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) { 18485 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr(); 18486 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 18487 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18488 relation.setEffectType(EffectType.select); 18489 ResultColumn targetColumn = (ResultColumn) aliasColumnMap 18490 .getValueAtIndex(aliasColumnMap.size() - resultColumnSize + x); 18491 relation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 18492 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18493 } 18494 } 18495 } 18496 } 18497 } else if (tableItem instanceof Table) { 18498 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18499 if (pivotedColumns.contains(tableColumn)) { 18500 continue; 18501 } 18502 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18503 relation.setEffectType(EffectType.select); 18504 relation.setTarget(new ResultColumnRelationshipElement( 18505 aliasColumnMap.get(tableColumn.getColumnObject().toString()))); 18506 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18507 } 18508 } 18509 } 18510 18511 ResultSet resultSet = modelFactory.createResultSet(stmt, 18512 isTopResultSet(stmt) && isShowTopSelectResultSet()); 18513 TResultColumnList columnList = stmt.getResultColumnList(); 18514 for (int i = 0; i < columnList.size(); i++) { 18515 TResultColumn column = columnList.getResultColumn(i); 18516 ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i); 18517 if (resultColumn.getColumnObject() instanceof TResultColumn) { 18518 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 18519 if (columnObject.getFieldAttr() != null) { 18520 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 18521 resultColumn.setShowStar(false); 18522 for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) { 18523 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject()); 18524 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18525 relation.setEffectType(EffectType.select); 18526 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 18527 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18528 } 18529 } else { 18530 for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) { 18531 if (getColumnName(columnObject.getFieldAttr()) 18532 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18533 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18534 relation.setEffectType(EffectType.select); 18535 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18536 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18537 break; 18538 } 18539 } 18540 } 18541 } else if (columnObject.getExpr() != null && columnObject.getExpr() 18542 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 18543 for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) { 18544 if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand()) 18545 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18546 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18547 relation.setEffectType(EffectType.select); 18548 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18549 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18550 break; 18551 } 18552 } 18553 } else if (columnObject.getExpr() != null && columnObject.getExpr() 18554 .getExpressionType() == EExpressionType.function_t) { 18555 Function function = (Function) createFunction(columnObject.getExpr().getFunctionCall()); 18556 for (ResultColumn arg : function.getColumns()) { 18557 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18558 relation.setEffectType(EffectType.select); 18559 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18560 relation.addSource(new ResultColumnRelationshipElement(arg)); 18561 } 18562 } 18563 } 18564 } 18565 } else { 18566 ResultSet resultSet = modelFactory.createResultSet(stmt, isTopResultSet(stmt)); 18567 TResultColumnList columnList = stmt.getResultColumnList(); 18568 for (int i = 0; i < columnList.size(); i++) { 18569 TResultColumn column = columnList.getResultColumn(i); 18570 ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i); 18571 if (resultColumn.getColumnObject() instanceof TResultColumn) { 18572 boolean fromFunction = false; 18573 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 18574 TObjectName resultColumnFieldAttr = columnObject.getFieldAttr(); 18575 List<TObjectName> resultColumnNames = new ArrayList<TObjectName>(); 18576 if (resultColumnFieldAttr != null) { 18577 resultColumnNames.add(resultColumnFieldAttr); 18578 } else if (columnObject.getExpr() != null 18579 && column.getExpr().getExpressionType() == EExpressionType.function_t) { 18580 extractFunctionObjectNames(column.getExpr().getFunctionCall(), resultColumnNames); 18581 fromFunction = true; 18582 } 18583 18584 if (!resultColumnNames.isEmpty()) { 18585 for (TObjectName resultColumnName : resultColumnNames) { 18586 if ("*".equals(getColumnName(resultColumnName))) { 18587 resultColumn.setShowStar(false); 18588 int index = 0; 18589 for (int k = 0; k < tables.size(); k++) { 18590 Object tableItem = tables.get(k); 18591 if (tableItem instanceof ResultSet && !(tableItem instanceof QueryTable)) { 18592 for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) { 18593 ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x); 18594 if (pivotedColumns.contains(tableColumn)) { 18595 continue; 18596 } 18597 if (tableColumn.getColumnObject() instanceof TObjectName) { 18598 resultColumn.bindStarLinkColumn( 18599 (TObjectName) tableColumn.getColumnObject()); 18600 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18601 relation.setEffectType(EffectType.select); 18602 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 18603 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18604 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 18605 if (((TResultColumn) tableColumn.getColumnObject()) 18606 .getFieldAttr() != null) { 18607 if (tableColumn.hasStarLinkColumn()) { 18608 for (int z = 0; z < tableColumn.getStarLinkColumnList() 18609 .size(); z++) { 18610 ResultColumn resultColumn1 = modelFactory 18611 .createResultColumn((ResultSet) tableItem, 18612 tableColumn.getStarLinkColumnList().get(z)); 18613 DataFlowRelationship relation = modelFactory 18614 .createDataFlowRelation(); 18615 relation.setEffectType(EffectType.select); 18616 relation.setTarget( 18617 new ResultColumnRelationshipElement(resultColumn)); 18618 relation.addSource( 18619 new ResultColumnRelationshipElement(resultColumn1)); 18620 tableColumn.getStarLinkColumns().remove(getColumnName( 18621 tableColumn.getStarLinkColumnList().get(z))); 18622 z--; 18623 } 18624 } else { 18625 resultColumn.bindStarLinkColumn( 18626 ((TResultColumn) tableColumn.getColumnObject()) 18627 .getFieldAttr()); 18628 DataFlowRelationship relation = modelFactory 18629 .createDataFlowRelation(); 18630 relation.setEffectType(EffectType.select); 18631 relation.setTarget( 18632 new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject()) 18633 .getFieldAttr())); 18634 relation.addSource( 18635 new ResultColumnRelationshipElement(tableColumn)); 18636 } 18637 } else if (((TResultColumn) tableColumn.getColumnObject()) 18638 .getExpr() != null) { 18639 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()) 18640 .getExpr(); 18641 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 18642 TObjectName columnName = new TObjectName(); 18643 columnName.setString(expr.toString()); 18644 resultColumn.bindStarLinkColumn(columnName); 18645 DataFlowRelationship relation = modelFactory 18646 .createDataFlowRelation(); 18647 relation.setEffectType(EffectType.select); 18648 relation.setTarget( 18649 new ResultColumnRelationshipElement(resultColumn, columnName)); 18650 relation.addSource( 18651 new ResultColumnRelationshipElement(tableColumn)); 18652 } 18653 } 18654 } 18655 } 18656 } else if (tableItem instanceof Table) { 18657 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18658 if (pivotedColumns.contains(tableColumn)) { 18659 continue; 18660 } 18661 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(), 18662 index); 18663 index++; 18664 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18665 relation.setEffectType(EffectType.select); 18666 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 18667 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18668 } 18669 } else if (tableItem instanceof QueryTable) { 18670 for (ResultColumn tableColumn : ((QueryTable) tableItem).getColumns()) { 18671 if (pivotedColumns.contains(tableColumn)) { 18672 continue; 18673 } 18674 TObjectName column1 = new TObjectName(); 18675 column1.setString(tableColumn.getName()); 18676 resultColumn.bindStarLinkColumn(column1, index); 18677 index++; 18678 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18679 relation.setEffectType(EffectType.select); 18680 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, column1)); 18681 relation.addSource(new ResultColumnRelationshipElement(tableColumn), false); 18682 } 18683 } 18684 } 18685 } else { 18686 ResultColumn pivotedTableColumn = getPivotedTableColumn(pivotedTable, resultColumnName); 18687 if (pivotedTableColumn != null) { 18688 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18689 relation.setEffectType(EffectType.select); 18690 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18691 relation.addSource(new ResultColumnRelationshipElement(pivotedTableColumn)); 18692 } else { 18693 for (int k = 0; k < tables.size(); k++) { 18694 Object tableItem = tables.get(k); 18695 if (tableItem instanceof ResultSet) { 18696 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 18697 if (DlineageUtil 18698 .getIdentifierNormalColumnName(tableColumn.getName()).equals(getColumnName(resultColumnName))) { 18699 if (fromFunction) { 18700 Function function = (Function)createPivotedFunction(column.getExpr().getFunctionCall(), tableColumn); 18701 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18702 relation.setEffectType(EffectType.select); 18703 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18704 if (function.getColumns() != null && !function.getColumns().isEmpty()) { 18705 for (ResultColumn functionColumn : function.getColumns()) { 18706 relation.addSource(new ResultColumnRelationshipElement(functionColumn)); 18707 } 18708 } 18709 } else { 18710 DataFlowRelationship relation = modelFactory 18711 .createDataFlowRelation(); 18712 relation.setEffectType(EffectType.select); 18713 relation.setTarget( 18714 new ResultColumnRelationshipElement(resultColumn)); 18715 relation.addSource( 18716 new ResultColumnRelationshipElement(tableColumn)); 18717 } 18718 break; 18719 } 18720 } 18721 } else if (tableItem instanceof Table) { 18722 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18723 if (getColumnName(resultColumnName).equals(DlineageUtil 18724 .getIdentifierNormalColumnName(tableColumn.getName()))) { 18725 DataFlowRelationship relation = modelFactory 18726 .createDataFlowRelation(); 18727 relation.setEffectType(EffectType.select); 18728 relation.setTarget( 18729 new ResultColumnRelationshipElement(resultColumn)); 18730 relation.addSource( 18731 new TableColumnRelationshipElement(tableColumn)); 18732 break; 18733 } 18734 } 18735 } 18736 } 18737 } 18738 } 18739 } 18740 } else if (columnObject.getExpr() != null && columnObject.getExpr() 18741 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 18742 for (int k = 0; k < tables.size(); k++) { 18743 Object tableItem = tables.get(k); 18744 if (tableItem instanceof ResultSet) { 18745 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 18746 if (columnObject.getExpr().getRightOperand().getObjectOperand() != null 18747 && getColumnName( 18748 columnObject.getExpr().getRightOperand().getObjectOperand()) 18749 .equals(DlineageUtil.getIdentifierNormalColumnName( 18750 tableColumn.getName()))) { 18751 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18752 relation.setEffectType(EffectType.select); 18753 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18754 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18755 break; 18756 } else if (columnObject.getExpr().getRightOperand() 18757 .getExpressionType() == EExpressionType.function_t) { 18758 List<TExpression> expressions = new ArrayList<TExpression>(); 18759 getFunctionExpressions(expressions, new ArrayList<TExpression>(), 18760 columnObject.getExpr().getRightOperand().getFunctionCall()); 18761 for (int j = 0; j < expressions.size(); j++) { 18762 columnsInExpr visitor = new columnsInExpr(); 18763 expressions.get(j).inOrderTraverse(visitor); 18764 List<TObjectName> objectNames = visitor.getObjectNames(); 18765 if (objectNames == null) { 18766 continue; 18767 } 18768 for (TObjectName columnName : objectNames) { 18769 if (getColumnName(columnName).equals(DlineageUtil 18770 .getIdentifierNormalColumnName(tableColumn.getName()))) { 18771 DataFlowRelationship relation = modelFactory 18772 .createDataFlowRelation(); 18773 relation.setEffectType(EffectType.select); 18774 relation.setTarget( 18775 new ResultColumnRelationshipElement(resultColumn)); 18776 relation.addSource( 18777 new ResultColumnRelationshipElement(tableColumn)); 18778 break; 18779 } 18780 } 18781 } 18782 } 18783 } 18784 } else if (tableItem instanceof Table) { 18785 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18786 if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand()) 18787 .equals(DlineageUtil 18788 .getIdentifierNormalColumnName(tableColumn.getName()))) { 18789 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18790 relation.setEffectType(EffectType.select); 18791 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18792 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18793 break; 18794 } 18795 } 18796 } 18797 } 18798 } 18799 } 18800 } 18801 } 18802 18803 analyzeSelectIntoClause(stmt); 18804 } 18805 18806 private Function createPivotedFunction(TFunctionCall functionCall, ResultColumn sourceColumn) { 18807 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 18808 ResultColumn column = modelFactory.createFunctionResultColumn(function, 18809 ((TFunctionCall) functionCall).getFunctionName()); 18810 if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) { 18811 // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP 18812 // COUNT特殊处理,不和参数关联 18813 if (option.isShowCountTableColumn()) { 18814 analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn); 18815 } 18816 } else { 18817 analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn); 18818 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function)); 18819 if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) { 18820 ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next(); 18821 if (functionTableModel.getColumns() != null) { 18822 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 18823 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18824 relation.setEffectType(EffectType.select); 18825 relation.setTarget(new ResultColumnRelationshipElement(column)); 18826 relation.addSource(new ResultColumnRelationshipElement( 18827 functionTableModel.getColumns().get(j))); 18828 } 18829 } 18830 } 18831 } 18832 return function; 18833 } 18834 18835 private void analyzePivotedFunctionArgumentsDataFlowRelation(ResultColumn column, TFunctionCall functionCall, 18836 ResultColumn sourceColumn) { 18837 List<TExpression> directExpressions = new ArrayList<TExpression>(); 18838 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 18839 18840 getFunctionExpressions(directExpressions, indirectExpressions, functionCall); 18841 18842 for (int j = 0; j < directExpressions.size(); j++) { 18843 columnsInExpr visitor = new columnsInExpr(); 18844 directExpressions.get(j).inOrderTraverse(visitor); 18845 18846 List<TObjectName> objectNames = visitor.getObjectNames(); 18847 List<TParseTreeNode> constants = visitor.getConstants(); 18848 18849 if (objectNames != null) { 18850 for (TObjectName name : objectNames) { 18851 if (DlineageUtil.compareColumnIdentifier(name.toString(), sourceColumn.getName())) { 18852 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18853 relation.setEffectType(EffectType.select); 18854 relation.setTarget(new ResultColumnRelationshipElement(column)); 18855 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 18856 } 18857 } 18858 } 18859 if (constants != null) { 18860 for (TParseTreeNode name : constants) { 18861 if (name.toString().equals(sourceColumn.getName())) { 18862 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18863 relation.setEffectType(EffectType.select); 18864 relation.setTarget(new ResultColumnRelationshipElement(column)); 18865 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 18866 } 18867 } 18868 } 18869 } 18870 } 18871 18872 private void extractFunctionObjectNames(TFunctionCall functionCall, List<TObjectName> resultColumnNames) { 18873 List<TExpression> directExpressions = new ArrayList<TExpression>(); 18874 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 18875 18876 getFunctionExpressions(directExpressions, indirectExpressions, functionCall); 18877 18878 for (int j = 0; j < directExpressions.size(); j++) { 18879 columnsInExpr visitor = new columnsInExpr(); 18880 directExpressions.get(j).inOrderTraverse(visitor); 18881 18882 List<TObjectName> objectNames = visitor.getObjectNames(); 18883 List<TParseTreeNode> functions = visitor.getFunctions(); 18884 List<TParseTreeNode> constants = visitor.getConstants(); 18885 18886 if (objectNames != null) { 18887 resultColumnNames.addAll(objectNames); 18888 } 18889 18890 if (constants != null) { 18891 for(TParseTreeNode item: constants) { 18892 if(item instanceof TConstant && ((TConstant) item).getLiteralType().getText().equals(ELiteralType.string_et.getText())) { 18893 TObjectName object = new TObjectName(); 18894 object.setString(item.toString()); 18895 resultColumnNames.add(object); 18896 } 18897 } 18898 } 18899 18900 if (functions != null && !functions.isEmpty()) { 18901 for (TParseTreeNode function : functions) { 18902 if (function instanceof TFunctionCall) { 18903 extractFunctionObjectNames((TFunctionCall) function, resultColumnNames); 18904 } 18905 } 18906 } 18907 } 18908 } 18909 18910 private String getResultColumnString(TResultColumn resultColumn) { 18911 if (resultColumn.getAliasClause() != null) { 18912 return resultColumn.getAliasClause().toString(); 18913 } 18914 return resultColumn.toString(); 18915 } 18916 18917 private void analyzeBigQueryUnnest(TSelectSqlStatement stmt, TTable table) { 18918 Table unnestTable = modelFactory.createTableFromCreateDDL(table, false, getTempTableName(table)); 18919 unnestTable.setSubType(SubType.unnest); 18920 TUnnestClause clause = table.getUnnestClause(); 18921 TExpression arrayExpr = clause.getArrayExpr(); 18922 if (arrayExpr == null){ 18923 if (clause.getColumns() != null) { 18924 for (TObjectName column : clause.getColumns()) { 18925 if (clause.getDerivedColumnList() != null) { 18926 unnestTable.setCreateTable(true); 18927 for (int i = 0; i < clause.getDerivedColumnList().size(); i++) { 18928 TObjectName columnName = new TObjectName(); 18929 columnName.setString(column.getColumnNameOnly() + "." 18930 + clause.getDerivedColumnList().getObjectName(i).getColumnNameOnly()); 18931 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true); 18932 List<TObjectName> columns = new ArrayList<TObjectName>(); 18933 columns.add(column); 18934 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 18935 } 18936 } 18937 else { 18938 unnestTable.setCreateTable(true); 18939 boolean find = false; 18940 if (column.getSourceTable() != null && modelManager.getModel(column.getSourceTable()) instanceof Table) { 18941 Table sourceTable = (Table)modelManager.getModel(column.getSourceTable()); 18942 if(sourceTable!=null) { 18943 for(TableColumn tableColumn: sourceTable.getColumns()) { 18944 if(tableColumn.isStruct()) { 18945 List<String> names = SQLUtil.parseNames(tableColumn.getName()); 18946 if (names.get(0).equalsIgnoreCase(column.getColumnNameOnly())) { 18947 TObjectName columnName = new TObjectName(); 18948 columnName.setString(tableColumn.getName()); 18949 TableColumn unnestTableColumn = modelFactory.createTableColumn(unnestTable, 18950 columnName, true); 18951 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18952 relation.setEffectType(EffectType.select); 18953 relation.setTarget(new TableColumnRelationshipElement(unnestTableColumn)); 18954 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18955 find = true; 18956 } 18957 } 18958 } 18959 } 18960 } 18961 if (!find) { 18962 TObjectName colName = column; 18963 if (table.getAliasClause() != null && table.getAliasClause().getAliasName() != null) { 18964 colName = table.getAliasClause().getAliasName(); 18965 } 18966 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, colName, true); 18967 List<TObjectName> columns = new ArrayList<TObjectName>(); 18968 columns.add(column); 18969 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 18970 } 18971 } 18972 } 18973 } 18974 return; 18975 } 18976 List<TExpression> expressions = new ArrayList<TExpression>(); 18977 TExpressionList values = arrayExpr.getExprList(); 18978 if (values == null) { 18979 expressions.add(arrayExpr); 18980 } 18981 else { 18982 for(TExpression value: values) { 18983 expressions.add(value); 18984 } 18985 } 18986 for (TExpression value : expressions) { 18987 unnestTable.setCreateTable(true); 18988 if (value.getExpressionType() == EExpressionType.simple_object_name_t) { 18989 if (table.getAliasClause() != null) { 18990 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 18991 table.getAliasClause().getAliasName(), true); 18992 columnsInExpr visitor = new columnsInExpr(); 18993 value.inOrderTraverse(visitor); 18994 List<TObjectName> columns = visitor.getObjectNames(); 18995 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 18996 } else { 18997 TResultColumnList resultColumnList = stmt.getResultColumnList(); 18998 for (int i = 0; i < resultColumnList.size(); i++) { 18999 TObjectName firstColumn = new TObjectName(); 19000 firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly()); 19001 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19002 columnsInExpr visitor = new columnsInExpr(); 19003 value.inOrderTraverse(visitor); 19004 List<TObjectName> columns = visitor.getObjectNames(); 19005 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 19006 } 19007 } 19008 } else if (value.getExpressionType() == EExpressionType.function_t) { 19009 if (table.getAliasClause() != null) { 19010 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 19011 table.getAliasClause().getAliasName(), true); 19012 columnsInExpr visitor = new columnsInExpr(); 19013 value.inOrderTraverse(visitor); 19014 List<TParseTreeNode> functions = visitor.getFunctions(); 19015 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.select, null); 19016 } else { 19017 TResultColumnList resultColumnList = stmt.getResultColumnList(); 19018 for (int i = 0; i < resultColumnList.size(); i++) { 19019 TObjectName firstColumn = new TObjectName(); 19020 firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly()); 19021 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19022 columnsInExpr visitor = new columnsInExpr(); 19023 value.inOrderTraverse(visitor); 19024 List<TObjectName> columns = visitor.getObjectNames(); 19025 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 19026 } 19027 } 19028 } else if (value.getExpressionType() == EExpressionType.simple_constant_t) { 19029 if (table.getAliasClause() != null) { 19030 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 19031 table.getAliasClause().getAliasName(), true); 19032 columnsInExpr visitor = new columnsInExpr(); 19033 value.inOrderTraverse(visitor); 19034 List<TParseTreeNode> constants = visitor.getConstants(); 19035 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19036 } else { 19037 TObjectName firstColumn = new TObjectName(); 19038 firstColumn.setString("f0_"); 19039 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19040 columnsInExpr visitor = new columnsInExpr(); 19041 value.inOrderTraverse(visitor); 19042 List<TParseTreeNode> constants = visitor.getConstants(); 19043 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19044 } 19045 } else if (value.getExpressionType() == EExpressionType.list_t) { 19046 if (arrayExpr.getTypeName() != null && arrayExpr.getTypeName().getColumnDefList() != null) { 19047 for (int i = 0; i < arrayExpr.getTypeName().getColumnDefList().size(); i++) { 19048 TColumnDefinition column = arrayExpr.getTypeName().getColumnDefList().getColumn(i); 19049 if (column != null && column.getColumnName() != null) { 19050 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 19051 column.getColumnName(), true); 19052 columnsInExpr visitor = new columnsInExpr(); 19053 value.getExprList().getExpression(i).inOrderTraverse(visitor); 19054 List<TParseTreeNode> constants = visitor.getConstants(); 19055 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19056 } 19057 } 19058 } else { 19059 for (int i = 0; i < value.getExprList().size(); i++) { 19060 TObjectName firstColumn = new TObjectName(); 19061 firstColumn.setString("f" + i + "_"); 19062 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19063 columnsInExpr visitor = new columnsInExpr(); 19064 value.getExprList().getExpression(i).inOrderTraverse(visitor); 19065 List<TParseTreeNode> constants = visitor.getConstants(); 19066 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19067 } 19068 } 19069 } else if (value.getExpressionType() == EExpressionType.subquery_t) { 19070 analyzeSelectStmt(value.getSubQuery()); 19071 ResultSet resultSet = (ResultSet) modelManager.getModel(value.getSubQuery()); 19072 if (resultSet != null) { 19073 for (int i = 0; i < resultSet.getColumns().size(); i++) { 19074 TObjectName columnName = new TObjectName(); 19075 if(resultSet.getColumns().get(i).getAlias()!=null) { 19076 columnName.setString(resultSet.getColumns().get(i).getAlias()); 19077 } 19078 else { 19079 columnName.setString(getColumnName(resultSet.getColumns().get(i).getName())); 19080 } 19081 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true); 19082 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19083 relation.setEffectType(EffectType.select); 19084 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 19085 relation.addSource( 19086 new ResultColumnRelationshipElement(resultSet.getColumns().get(i))); 19087 } 19088 } 19089 } 19090 } 19091 } 19092 19093 private void analyzePrestoUnnest(TSelectSqlStatement stmt, TTable table) { 19094 List<Table> tables = new ArrayList<Table>(); 19095 TTable targetTable = stmt.getTables().getTable(0); 19096 Table stmtTable = modelFactory.createTable(targetTable); 19097 Object sourceTable = null; 19098 if (targetTable.getSubquery() != null) { 19099 analyzeSelectStmt(targetTable.getSubquery()); 19100 if (targetTable.getSubquery().isCombinedQuery()) { 19101 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(targetTable.getSubquery()); 19102 sourceTable = sourceResultSet; 19103 } else if (targetTable.getSubquery().getResultColumnList() != null) { 19104 ResultSet sourceResultSet = (ResultSet) modelManager 19105 .getModel(targetTable.getSubquery().getResultColumnList()); 19106 sourceTable = sourceResultSet; 19107 } else if (targetTable.getSubquery().getValueClause() != null) { 19108 List<TResultColumnList> rowList = targetTable.getSubquery().getValueClause().getRows(); 19109 if (rowList != null && rowList.size() > 0) { 19110 Table valuesTable = modelFactory.createTableByName("Values-Table", true); 19111 int columnCount = rowList.get(0).size(); 19112 for (int j = 1; j <= columnCount; j++) { 19113 TObjectName columnName = new TObjectName(); 19114 TResultColumn columnObject = rowList.get(0).getResultColumn(j - 1); 19115 if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) { 19116 columnName.setString(columnObject.getExpr().getLeftOperand().toString()); 19117 } else { 19118 columnName.setString(columnObject.getExpr().toString()); 19119 } 19120 modelFactory.createTableColumn(valuesTable, columnName, true); 19121 } 19122 valuesTable.setCreateTable(true); 19123 valuesTable.setSubType(SubType.values_table); 19124 sourceTable = valuesTable; 19125 } 19126 } 19127 } 19128 tables.add(stmtTable); 19129 Table unnestTable = modelFactory.createTable(table); 19130 unnestTable.setSubType(SubType.unnest); 19131 tables.add(unnestTable); 19132 if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null 19133 && table.getUnnestClause().getColumns() != null) { 19134 int unnestTableSize = table.getUnnestClause().getColumns().size(); 19135 for (int i = 0; i < table.getAliasClause().getColumns().size(); i++) { 19136 TableColumn sourceColumn = null; 19137 if (unnestTableSize > i) { 19138 sourceColumn = modelFactory.createTableColumn(stmtTable, 19139 table.getUnnestClause().getColumns().getObjectName(i), true); 19140 if (sourceTable instanceof Table) { 19141 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19142 relation.setEffectType(EffectType.select); 19143 relation.setTarget(new TableColumnRelationshipElement(sourceColumn)); 19144 relation.addSource( 19145 new TableColumnRelationshipElement(((Table) sourceTable).getColumns().get(i))); 19146 } else if (sourceTable instanceof ResultSet) { 19147 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19148 relation.setEffectType(EffectType.select); 19149 relation.setTarget(new TableColumnRelationshipElement(sourceColumn)); 19150 relation.addSource( 19151 new ResultColumnRelationshipElement(((ResultSet) sourceTable).getColumns().get(i))); 19152 } 19153 } else { 19154 sourceColumn = modelFactory.createTableColumn(stmtTable, 19155 table.getUnnestClause().getColumns().getObjectName(unnestTableSize - 1), true); 19156 } 19157 TableColumn targetColumn = modelFactory.createTableColumn(unnestTable, 19158 table.getAliasClause().getColumns().getObjectName(i), true); 19159 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19160 relation.setEffectType(EffectType.select); 19161 relation.setTarget(new TableColumnRelationshipElement(targetColumn)); 19162 relation.addSource(new TableColumnRelationshipElement(sourceColumn)); 19163 } 19164 } 19165 19166 ResultSet resultSet = modelFactory.createResultSet(stmt, 19167 isTopResultSet(stmt) && isShowTopSelectResultSet()); 19168 TResultColumnList columnList = stmt.getResultColumnList(); 19169 for (int i = 0; i < columnList.size(); i++) { 19170 TResultColumn column = columnList.getResultColumn(i); 19171 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i); 19172 if (resultColumn.getColumnObject() instanceof TResultColumn) { 19173 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 19174 if (columnObject.getFieldAttr() != null) { 19175 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 19176 for (int k = 0; k < tables.size(); k++) { 19177 Table tableItem = tables.get(k); 19178 for (TableColumn tableColumn : tableItem.getColumns()) { 19179 resultColumn.bindStarLinkColumn(tableColumn.getColumnObject()); 19180 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19181 relation.setEffectType(EffectType.select); 19182 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject())); 19183 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19184 } 19185 } 19186 } else { 19187 boolean match = false; 19188 for (int k = 0; k < tables.size(); k++) { 19189 Table tableItem = tables.get(k); 19190 for (TableColumn tableColumn : tableItem.getColumns()) { 19191 if (getColumnName(columnObject.getFieldAttr()) 19192 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19193 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19194 relation.setEffectType(EffectType.select); 19195 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19196 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19197 match = true; 19198 } 19199 } 19200 } 19201 if (!match) { 19202 TableColumn tableColumn = modelFactory.createTableColumn(stmtTable, 19203 columnObject.getFieldAttr(), false); 19204 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19205 relation.setEffectType(EffectType.select); 19206 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19207 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19208 } 19209 } 19210 } 19211 } 19212 } 19213 } 19214 19215 private void analyzeLateralView(TSelectSqlStatement stmt, TTable table, ArrayList<TLateralView> lateralViews) { 19216 List<Object> tables = new ArrayList<Object>(); 19217 Object stmtTable = null; 19218 if(table.getSubquery()!=null) { 19219 stmtTable = modelFactory.createQueryTable(table); 19220 tables.add(stmtTable); 19221 } 19222 else { 19223 stmtTable = modelFactory.createTable(table); 19224 tables.add(stmtTable); 19225 } 19226 for (int i = 0; i < lateralViews.size(); i++) { 19227 TLateralView lateralView = lateralViews.get(i); 19228 TFunctionCall functionCall = lateralView.getUdtf(); 19229 List<TExpression> expressions = new ArrayList<TExpression>(); 19230 if (functionCall == null) { 19231 continue; 19232 } 19233 Function function = modelFactory.createFunction(functionCall); 19234 ResultColumn column = modelFactory.createFunctionResultColumn(function, 19235 ((TFunctionCall) functionCall).getFunctionName()); 19236 19237 Table lateralTable = null; 19238 if (lateralView.getTableAlias() != null) { 19239 lateralTable = modelFactory.createTableByName(lateralView.getTableAlias().getAliasName(), true); 19240 } else { 19241 lateralTable = modelFactory.createTableByName(functionCall.toString(), true); 19242 } 19243 19244 for (int j = 0; j < lateralView.getColumnAliasList().size(); j++) { 19245 TObjectName viewColumn = lateralView.getColumnAliasList().getObjectName(j); 19246 TableColumn tableColumn = modelFactory.createTableColumn(lateralTable, viewColumn, true); 19247 19248 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19249 relation.setEffectType(EffectType.select); 19250 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 19251 relation.addSource(new ResultColumnRelationshipElement(column)); 19252 } 19253 19254 getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall); 19255 for (int j = 0; j < expressions.size(); j++) { 19256 columnsInExpr visitor = new columnsInExpr(); 19257 expressions.get(j).inOrderTraverse(visitor); 19258 List<TObjectName> objectNames = visitor.getObjectNames(); 19259 if (objectNames == null) { 19260 continue; 19261 } 19262 for (TObjectName columnName : objectNames) { 19263 boolean match = false; 19264 for (int k = 0; k < tables.size(); k++) { 19265 Object item = tables.get(k); 19266 if(item instanceof Table) { 19267 Table tableItem = (Table)item; 19268 for (TableColumn tableColumn : tableItem.getColumns()) { 19269 if (getColumnName(columnName) 19270 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19271 match = true; 19272 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19273 relation.setEffectType(EffectType.select); 19274 relation.setTarget(new ResultColumnRelationshipElement(column)); 19275 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19276 } 19277 } 19278 } 19279 else { 19280 ResultSet tableItem = (ResultSet)item; 19281 for (ResultColumn tableColumn : tableItem.getColumns()) { 19282 if (getColumnName(columnName) 19283 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19284 match = true; 19285 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19286 relation.setEffectType(EffectType.select); 19287 relation.setTarget(new ResultColumnRelationshipElement(column)); 19288 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19289 } 19290 } 19291 } 19292 } 19293 if (!match) { 19294 if(stmtTable instanceof Table) { 19295 TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable, columnName, false); 19296 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19297 relation.setEffectType(EffectType.select); 19298 relation.setTarget(new ResultColumnRelationshipElement(column)); 19299 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19300 } 19301 else { 19302 ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable, columnName, false); 19303 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19304 relation.setEffectType(EffectType.select); 19305 relation.setTarget(new ResultColumnRelationshipElement(column)); 19306 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19307 } 19308 } 19309 } 19310 List<TParseTreeNode> constants = visitor.getConstants(); 19311 if (!constants.isEmpty()) { 19312 if (option.isShowConstantTable()) { 19313 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 19314 for (TParseTreeNode constant : constants) { 19315 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19316 relation.setEffectType(EffectType.select); 19317 relation.setTarget(new ResultColumnRelationshipElement(column)); 19318 if (constant instanceof TConstant) { 19319 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 19320 (TConstant) constant); 19321 relation.addSource(new ConstantRelationshipElement(constantColumn)); 19322 } else if (constant instanceof TObjectName) { 19323 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 19324 (TObjectName) constant, false); 19325 relation.addSource(new ConstantRelationshipElement(constantColumn)); 19326 } 19327 } 19328 } 19329 } 19330 19331 List<TParseTreeNode> functions = visitor.getFunctions(); 19332 if (functions != null && !functions.isEmpty()) { 19333 analyzeFunctionDataFlowRelation(column, functions, EffectType.function); 19334 } 19335 } 19336 tables.add(lateralTable); 19337 } 19338 19339 ResultSet resultSet = modelFactory.createResultSet(stmt, 19340 isTopResultSet(stmt) && isShowTopSelectResultSet()); 19341 TResultColumnList columnList = stmt.getResultColumnList(); 19342 for (int i = 0; i < columnList.size(); i++) { 19343 TResultColumn column = columnList.getResultColumn(i); 19344 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i); 19345 if (resultColumn.getColumnObject() instanceof TResultColumn) { 19346 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 19347 if (columnObject.getFieldAttr() != null) { 19348 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 19349 for (int k = 0; k < tables.size(); k++) { 19350 Object item = tables.get(k); 19351 if(item instanceof Table) { 19352 Table tableItem = (Table)item; 19353 for (TableColumn tableColumn : tableItem.getColumns()) { 19354 resultColumn.bindStarLinkColumn(tableColumn.getColumnObject()); 19355 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19356 relation.setEffectType(EffectType.select); 19357 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject())); 19358 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19359 } 19360 } 19361 else { 19362 ResultSet tableItem = (ResultSet)item; 19363 for (ResultColumn tableColumn : tableItem.getColumns()) { 19364 TObjectName linkColumn = new TObjectName(); 19365 linkColumn.setString(tableColumn.getName()); 19366 resultColumn.bindStarLinkColumn(linkColumn); 19367 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19368 relation.setEffectType(EffectType.select); 19369 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, linkColumn)); 19370 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19371 } 19372 } 19373 } 19374 } else { 19375 boolean match = false; 19376 for (int k = 0; k < tables.size(); k++) { 19377 Object item = tables.get(k); 19378 if(item instanceof Table) { 19379 Table tableItem = (Table)item; 19380 for (TableColumn tableColumn : tableItem.getColumns()) { 19381 if (getColumnName(columnObject.getFieldAttr()) 19382 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19383 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19384 relation.setEffectType(EffectType.select); 19385 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19386 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19387 match = true; 19388 } 19389 } 19390 } 19391 else { 19392 ResultSet tableItem = (ResultSet)item; 19393 for (ResultColumn tableColumn : tableItem.getColumns()) { 19394 if (getColumnName(columnObject.getFieldAttr()) 19395 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19396 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19397 relation.setEffectType(EffectType.select); 19398 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19399 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19400 match = true; 19401 } 19402 } 19403 } 19404 } 19405 if (!match) { 19406 if(stmtTable instanceof Table) { 19407 TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable, 19408 columnObject.getFieldAttr(), false); 19409 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19410 relation.setEffectType(EffectType.select); 19411 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19412 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19413 } 19414 else { 19415 ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable, 19416 columnObject.getFieldAttr(), false); 19417 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19418 relation.setEffectType(EffectType.select); 19419 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19420 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19421 } 19422 } 19423 } 19424 } 19425 else if (columnObject.getExpr() != null 19426 && columnObject.getExpr().getExpressionType() == EExpressionType.function_t) { 19427 analyzeResultColumn(column, EffectType.select); 19428 for (int k = 0; k < tables.size(); k++) { 19429 Object item = tables.get(k); 19430 if (item instanceof Table) { 19431 Table tableItem = (Table) item; 19432 for (TableColumn tableColumn : tableItem.getColumns()) { 19433 if (getColumnName(resultColumn.getName()).equals( 19434 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19435 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19436 relation.setEffectType(EffectType.select); 19437 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19438 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19439 } 19440 } 19441 } else { 19442 ResultSet tableItem = (ResultSet) item; 19443 for (ResultColumn tableColumn : tableItem.getColumns()) { 19444 if (getColumnName(resultColumn.getName()).equals( 19445 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19446 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19447 relation.setEffectType(EffectType.select); 19448 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19449 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19450 } 19451 } 19452 } 19453 } 19454 } 19455 } 19456 } 19457 } 19458 19459 private boolean isFromFunction(TObjectName object) { 19460 19461 Stack<TParseTreeNode> nodes = object.getStartToken().getNodesStartFromThisToken(); 19462 if (nodes != null) { 19463 for (int i = 0; i < nodes.size(); i++) { 19464 if (nodes.get(i) instanceof TFunctionCall) { 19465 return true; 19466 } 19467 } 19468 } 19469 return false; 19470 } 19471 19472 private TResultColumnList getResultColumnList(TSelectSqlStatement stmt) { 19473 // Iterative DFS (left-first) to find the first non-combined query's result column list. 19474 // Avoids StackOverflow with deeply nested UNION trees. 19475 Deque<TSelectSqlStatement> stack = new ArrayDeque<>(); 19476 stack.push(stmt); 19477 while (!stack.isEmpty()) { 19478 TSelectSqlStatement current = stack.pop(); 19479 if (current.isCombinedQuery()) { 19480 // Push right first so left is processed first (stack is LIFO) 19481 if (current.getRightStmt() != null) stack.push(current.getRightStmt()); 19482 if (current.getLeftStmt() != null) stack.push(current.getLeftStmt()); 19483 } else { 19484 if (current.getResultColumnList() != null) { 19485 return current.getResultColumnList(); 19486 } 19487 } 19488 } 19489 return null; 19490 } 19491 19492 private void createPseudoImpactRelation(TCustomSqlStatement stmt, ResultSet resultSetModel, EffectType effectType) { 19493 if (stmt.getTables() != null) { 19494 for (int i = 0; i < stmt.getTables().size(); i++) { 19495 TTable table = stmt.getTables().getTable(i); 19496 if (modelManager.getModel(table) instanceof ResultSet) { 19497 ResultSet tableModel = (ResultSet) modelManager.getModel(table); 19498 if (tableModel != resultSetModel && !tableModel.getRelationRows().getHoldRelations().isEmpty()) { 19499 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 19500 impactRelation.setEffectType(effectType); 19501 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 19502 tableModel.getRelationRows())); 19503 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 19504 resultSetModel.getRelationRows())); 19505 } 19506 } else if (modelManager.getModel(table) instanceof Table) { 19507 Table tableModel = (Table) modelManager.getModel(table); 19508 if (!tableModel.getRelationRows().getHoldRelations().isEmpty()) { 19509 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 19510 impactRelation.setEffectType(effectType); 19511 impactRelation.addSource( 19512 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 19513 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 19514 resultSetModel.getRelationRows())); 19515 } 19516 } 19517 } 19518 } 19519 } 19520 19521 private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions, 19522 EffectType effectType) { 19523 for (int i = 0; i < functions.size(); i++) { 19524 TParseTreeNode functionCall = functions.get(i); 19525 if (functionCall instanceof TFunctionCall) { 19526 String functionName = DlineageUtil.getIdentifierNormalTableName( 19527 DlineageUtil.getFunctionNameWithArgNum((TFunctionCall) functionCall)); 19528 Procedure procedure = modelManager.getProcedureByName(functionName); 19529 if (procedure != null) { 19530 String procedureParent = getProcedureParentName(stmtStack.peek()); 19531 if (procedureParent != null) { 19532 Procedure caller = modelManager 19533 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 19534 if (caller != null) { 19535 CallRelationship callRelation = modelFactory.createCallRelation(); 19536 callRelation.setCallObject(functionCall); 19537 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 19538 callRelation.addSource(new ProcedureRelationshipElement(procedure)); 19539 if (isBuiltInFunctionName(((TFunctionCall)functionCall).getFunctionName())||isKeyword(((TFunctionCall)functionCall).getFunctionName())) { 19540 callRelation.setBuiltIn(true); 19541 } 19542 } 19543 } 19544 if (procedure.getProcedureObject() instanceof TCreateFunctionStmt) { 19545 TCreateFunctionStmt createFunction = (TCreateFunctionStmt)procedure.getProcedureObject(); 19546 TTypeName dataType = createFunction.getReturnDataType(); 19547 if (dataType!=null && dataType.getTypeOfList() != null && dataType.getTypeOfList().getColumnDefList() != null) { 19548 Object modelObject = modelManager.getModel(gspObject); 19549 if(modelObject instanceof ResultColumn) { 19550 ResultColumn resultColumn = (ResultColumn)modelObject; 19551 ResultSet resultSet = resultColumn.getResultSet(); 19552 for (int j = 0; j < dataType.getTypeOfList().getColumnDefList().size(); j++) { 19553 TObjectName columnName = new TObjectName(); 19554 if( dataType.getDataType() == EDataType.array_t) { 19555// columnName.setString(resultColumn.getName() + ".array." 19556// + dataType.getTypeOfList().getColumnDefList().getColumn(j) 19557// .getColumnName().getColumnNameOnly()); 19558 columnName.setString(resultColumn.getName() + "." 19559 + dataType.getTypeOfList().getColumnDefList().getColumn(j) 19560 .getColumnName().getColumnNameOnly()); 19561 } 19562 else { 19563 columnName.setString(resultColumn.getName() + "." 19564 + dataType.getTypeOfList().getColumnDefList().getColumn(j) 19565 .getColumnName().getColumnNameOnly()); 19566 } 19567 ResultColumn sturctColumn = modelFactory.createResultColumn(resultSet, columnName, 19568 true); 19569 sturctColumn.setStruct(true); 19570 Function sourceFunction = (Function)createFunction(functionCall); 19571 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19572 relation.setEffectType(effectType); 19573 relation.setTarget(new ResultColumnRelationshipElement(sturctColumn)); 19574 if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) { 19575 for (ResultColumn column : sourceFunction.getColumns()) { 19576 relation.addSource(new ResultColumnRelationshipElement(column)); 19577 } 19578 } 19579 } 19580 resultSet.getColumns().remove(resultColumn); 19581 } 19582 return; 19583 } 19584 } 19585 } 19586 } 19587 19588 if(gspObject instanceof TResultColumn) { 19589 TResultColumn resultColumn = (TResultColumn)gspObject; 19590 if(resultColumn.getAliasClause()!=null && resultColumn.getAliasClause().getColumns()!=null) { 19591 for(TObjectName columnName: resultColumn.getAliasClause().getColumns()) { 19592 analyzeFunctionDataFlowRelation(columnName, Arrays.asList(functionCall), effectType, null); 19593 } 19594 return; 19595 } 19596 } 19597 analyzeFunctionDataFlowRelation(gspObject, Arrays.asList(functionCall), effectType, null); 19598 } 19599 } 19600 19601 private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions, 19602 EffectType effectType, Process process) { 19603 19604 Object modelObject = modelManager.getModel(gspObject); 19605 if (modelObject == null) { 19606 if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) { 19607 modelObject = gspObject; 19608 } 19609 } 19610 19611 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19612 relation.setEffectType(effectType); 19613 relation.setProcess(process); 19614 19615 if (modelObject instanceof ResultColumn) { 19616 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 19617 19618 } else if (modelObject instanceof TableColumn) { 19619 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 19620 19621 } else { 19622 throw new UnsupportedOperationException(); 19623 } 19624 19625 for (int i = 0; i < functions.size(); i++) { 19626 TParseTreeNode functionCall = functions.get(i); 19627 19628 if (functionCall instanceof TFunctionCall) { 19629 TFunctionCall call = (TFunctionCall) functionCall; 19630 Procedure callee = modelManager.getProcedureByName( 19631 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call))); 19632 if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(call))) { 19633 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(call))); 19634 callee = modelManager.getProcedureByName( 19635 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call))); 19636 } 19637 19638 if (callee != null) { 19639 String procedureParent = getProcedureParentName(stmtStack.peek()); 19640 if (procedureParent != null) { 19641 Procedure caller = modelManager 19642 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 19643 if (caller != null) { 19644 CallRelationship callRelation = modelFactory.createCallRelation(); 19645 callRelation.setCallObject(functionCall); 19646 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 19647 callRelation.addSource(new ProcedureRelationshipElement(callee)); 19648 if (isBuiltInFunctionName(call.getFunctionName()) || isKeyword(call.getFunctionName())) { 19649 callRelation.setBuiltIn(true); 19650 } 19651 } 19652 } 19653 if (callee.getArguments() != null) { 19654 for (int j = 0; j < callee.getArguments().size(); j++) { 19655 Argument argument = callee.getArguments().get(j); 19656 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 19657 if(variable!=null) { 19658 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 19659 Transform transform = new Transform(); 19660 transform.setType(Transform.FUNCTION); 19661 transform.setCode(call); 19662 variable.getColumns().get(0).setTransform(transform); 19663 } 19664 Process callProcess = modelFactory.createProcess(call); 19665 variable.addProcess(callProcess); 19666 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), call, j, callProcess); 19667 } 19668 } 19669 } 19670 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil 19671 .getIdentifierNormalTableName(call.getFunctionName().toString())); 19672 if (functionTableModelObjs != null) { 19673 modelManager.bindModel(call, functionTableModelObjs.iterator().next()); 19674 for (Object functionTableModelObj : functionTableModelObjs) { 19675 if (functionTableModelObj instanceof ResultSet) { 19676 ResultSet resultSet = (ResultSet) functionTableModelObj; 19677 for (ResultColumn column : resultSet.getColumns()) { 19678 relation.addSource(new ResultColumnRelationshipElement(column)); 19679 } 19680 } 19681 } 19682 } 19683 continue; 19684 } 19685 } 19686 19687 19688 Object functionModel = createFunction(functionCall); 19689 if (functionModel instanceof Function) { 19690 Function sourceFunction = (Function)functionModel; 19691 if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) { 19692 for (ResultColumn column : sourceFunction.getColumns()) { 19693 relation.addSource(new ResultColumnRelationshipElement(column)); 19694 } 19695 } 19696 else if (functionCall instanceof TFunctionCall) { 19697 relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager 19698 .getModel(((TFunctionCall) functionCall).getFunctionName()))); 19699 } else if (functionCall instanceof TCaseExpression) { 19700 relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager 19701 .getModel(((TCaseExpression) functionCall).getWhenClauseItemList()))); 19702 } 19703 19704 if (sourceFunction != null && !sourceFunction.getRelationRows().getHoldRelations().isEmpty()) { 19705 boolean find = false; 19706 if (modelObject instanceof ResultColumn) { 19707 ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows(); 19708 if(targetRelationRows.hasRelation()) { 19709 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 19710 if(relationship.getSources().contains(sourceFunction.getRelationRows())) { 19711 find = true; 19712 break; 19713 } 19714 } 19715 } 19716 } 19717 else if (modelObject instanceof TableColumn) { 19718 TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows(); 19719 if(targetRelationRows.hasRelation()) { 19720 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 19721 if(relationship.getSources().contains(sourceFunction.getRelationRows())) { 19722 find = true; 19723 break; 19724 } 19725 } 19726 } 19727 } 19728 19729 if (!find) { 19730 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 19731 impactRelation.setEffectType(EffectType.select); 19732 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 19733 sourceFunction.getRelationRows())); 19734 if (modelObject instanceof ResultColumn) { 19735 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 19736 ((ResultColumn) modelObject).getResultSet().getRelationRows())); 19737 } else if (modelObject instanceof TableColumn) { 19738 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 19739 ((TableColumn) modelObject).getTable().getRelationRows())); 19740 } 19741 } 19742 } 19743 } else if (functionModel instanceof Table) { 19744 TFunctionCall call = (TFunctionCall) functionCall; 19745 String functionName = call.getFunctionName().toString(); 19746 boolean flag = false; 19747 if (functionName.indexOf(".") != -1) { 19748 String columnName = functionName.substring(functionName.indexOf(".") + 1); 19749 for (TableColumn tableColumn : ((Table) functionModel).getColumns()) { 19750 if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) { 19751 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 19752 relation.addSource(element); 19753 flag = true; 19754 break; 19755 } 19756 } 19757 } 19758 19759 if (!flag) { 19760 TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel, 19761 ((TFunctionCall) functionCall)); 19762 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 19763 relation.addSource(element); 19764 } 19765 } 19766 } 19767 19768 } 19769 19770 private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys, 19771 EffectType effectType) { 19772 analyzeSubqueryDataFlowRelation(gspObject, subquerys, effectType, null); 19773 } 19774 19775 private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys, 19776 EffectType effectType, Process process) { 19777 19778 Object modelObject = modelManager.getModel(gspObject); 19779 if (modelObject == null) { 19780 if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) { 19781 modelObject = gspObject; 19782 } 19783 } 19784 19785 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19786 relation.setEffectType(effectType); 19787 relation.setProcess(process); 19788 19789 if (modelObject instanceof ResultColumn) { 19790 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 19791 19792 } else if (modelObject instanceof TableColumn) { 19793 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 19794 19795 } else { 19796 throw new UnsupportedOperationException(); 19797 } 19798 19799 for (int i = 0; i < subquerys.size(); i++) { 19800 TSelectSqlStatement subquery = subquerys.get(i); 19801 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 19802 if (resultSetModel != null && resultSetModel.getColumns() != null) { 19803 for (ResultColumn column : resultSetModel.getColumns()) { 19804 relation.addSource(new ResultColumnRelationshipElement(column)); 19805 } 19806 } 19807 19808 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 19809 boolean find = false; 19810 if (modelObject instanceof ResultColumn) { 19811 ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows(); 19812 if(targetRelationRows.hasRelation()) { 19813 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 19814 if(relationship.getSources().contains(resultSetModel.getRelationRows())) { 19815 find = true; 19816 break; 19817 } 19818 } 19819 } 19820 } 19821 else if (modelObject instanceof TableColumn) { 19822 TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows(); 19823 if(targetRelationRows.hasRelation()) { 19824 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 19825 if(relationship.getSources().contains(resultSetModel.getRelationRows())) { 19826 find = true; 19827 break; 19828 } 19829 } 19830 } 19831 } 19832 19833 if (!find) { 19834 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 19835 impactRelation.setEffectType(EffectType.select); 19836 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 19837 resultSetModel.getRelationRows())); 19838 if (modelObject instanceof ResultColumn) { 19839 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 19840 ((ResultColumn) modelObject).getResultSet().getRelationRows())); 19841 } else if (modelObject instanceof TableColumn) { 19842 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 19843 ((TableColumn) modelObject).getTable().getRelationRows())); 19844 } 19845 } 19846 } 19847 } 19848 19849 } 19850 19851 private Object createFunction(TParseTreeNode functionCall) { 19852 if (functionCall instanceof TFunctionCall) { 19853 TFunctionCall functionObj = (TFunctionCall) functionCall; 19854 19855 // Generic structured-dataflow dispatch. When a vendor adapter (e.g. 19856 // Spark from_json+explode) returns a descriptor, model the function 19857 // as a structured generator: per-field result columns linked to 19858 // exact structured source paths such as nodes[*].key. When no 19859 // adapter matches, fall through to the existing function logic 19860 // unchanged. 19861 StructuredAdapterContext sctx = new StructuredAdapterContext(option.getVendor()); 19862 StructuredDataflowDescriptor sdescriptor = 19863 StructuredDataflowRegistry.defaultRegistry().describe(functionObj, sctx); 19864 if (sdescriptor != null) { 19865 Function structuredFn = createStructuredDataflowFunction(sdescriptor); 19866 if (structuredFn != null) { 19867 return structuredFn; 19868 } 19869 } 19870 19871 if (!isBuiltInFunctionName(functionObj.getFunctionName())) { 19872 TCustomSqlStatement stmt = stmtStack.peek(); 19873 String procedureParent = getProcedureParentName(stmt); 19874 if (procedureParent != null) { 19875 Procedure procedureCallee = modelManager.getProcedureByName(DlineageUtil 19876 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionObj))); 19877 if (procedureCallee != null) { 19878 if (procedureParent != null) { 19879 Procedure caller = modelManager 19880 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 19881 if (caller != null) { 19882 CallRelationship callRelation = modelFactory.createCallRelation(); 19883 callRelation.setCallObject(functionCall); 19884 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 19885 callRelation.addSource(new ProcedureRelationshipElement(procedureCallee)); 19886 if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){ 19887 callRelation.setBuiltIn(true); 19888 } 19889 } 19890 } 19891 if (procedureCallee.getArguments() != null) { 19892 for (int j = 0; j < procedureCallee.getArguments().size(); j++) { 19893 Argument argument = procedureCallee.getArguments().get(j); 19894 Variable variable = modelFactory.createVariable(procedureCallee, argument.getName(), false); 19895 if(variable!=null) { 19896 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 19897 Transform transform = new Transform(); 19898 transform.setType(Transform.FUNCTION); 19899 transform.setCode(functionObj); 19900 variable.getColumns().get(0).setTransform(transform); 19901 } 19902 Process process = modelFactory.createProcess(functionObj); 19903 variable.addProcess(process); 19904 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionObj, j, process); 19905 } 19906 } 19907 } 19908 } else { 19909 TFunctionCall call = (TFunctionCall)functionCall; 19910 String functionName = call.getFunctionName().toString(); 19911 if (functionName.indexOf(".") != -1) { 19912 Table functionTable = modelManager 19913 .getTableByName(functionName.substring(0, functionName.indexOf("."))); 19914 if (functionTable != null) { 19915 String columnName = functionName.substring(functionName.indexOf(".") + 1); 19916 for (TableColumn tableColumn : functionTable.getColumns()) { 19917 if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) { 19918 return functionTable; 19919 } 19920 } 19921 } 19922 } 19923 Function function = modelFactory.createFunction(call); 19924 if (procedureParent != null) { 19925 Procedure caller = modelManager 19926 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 19927 if (caller != null) { 19928 CallRelationship callRelation = modelFactory.createCallRelation(); 19929 callRelation.setCallObject(functionCall); 19930 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 19931 callRelation.addSource(new FunctionRelationshipElement(function)); 19932 if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){ 19933 callRelation.setBuiltIn(true); 19934 } 19935 } 19936 } 19937 } 19938 } 19939 } else if (isConstantFunction(functionObj.getFunctionName()) 19940 && (functionObj.getArgs() == null || functionObj.getArgs().size() == 0)) { 19941 if (option.isShowConstantTable()) { 19942 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 19943 modelFactory.createTableColumn(constantTable, functionObj); 19944 return constantTable; 19945 } else { 19946 return null; 19947 } 19948 } 19949 19950 if (functionObj.getFunctionType() == EFunctionType.struct_t) { 19951 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 19952 if(functionObj instanceof TTableFunction) { 19953 TTableFunction tableFunction = (TTableFunction) functionObj; 19954 if (tableFunction.getFieldValues() != null) { 19955 for (int i = 0; i < tableFunction.getFieldValues().size(); i++) { 19956 TResultColumn resultColumn = tableFunction.getFieldValues().getResultColumn(i); 19957 if (resultColumn.getAliasClause() != null) { 19958 ResultColumn column = modelFactory.createFunctionResultColumn(function, 19959 resultColumn.getAliasClause().getAliasName()); 19960 columnsInExpr visitor = new columnsInExpr(); 19961 resultColumn.getExpr().inOrderTraverse(visitor); 19962 List<TObjectName> objectNames = visitor.getObjectNames(); 19963 List<TParseTreeNode> functions = visitor.getFunctions(); 19964 if (functions != null && !functions.isEmpty()) { 19965 analyzeFunctionDataFlowRelation(column, functions, EffectType.function); 19966 } 19967 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 19968 if (subquerys != null && !subquerys.isEmpty()) { 19969 analyzeSubqueryDataFlowRelation(column, subquerys, EffectType.function); 19970 } 19971 analyzeDataFlowRelation(column, objectNames, EffectType.function, functions); 19972 List<TParseTreeNode> constants = visitor.getConstants(); 19973 analyzeConstantDataFlowRelation(column, constants, EffectType.function, functions); 19974 } else if (resultColumn.getFieldAttr() != null) { 19975 ResultColumn column = modelFactory.createFunctionResultColumn(function, 19976 resultColumn.getFieldAttr()); 19977 analyzeDataFlowRelation(column, Arrays.asList(resultColumn.getFieldAttr()), EffectType.function, null); 19978 } else if (resultColumn.getExpr() != null) { 19979 if (resultColumn.getExpr().getFunctionCall() != null) { 19980 Function resultColumnFunction = (Function) createFunction( 19981 resultColumn.getExpr().getFunctionCall()); 19982 String functionName = getResultSetName(function); 19983 for (int j = 0; j < resultColumnFunction.getColumns().size(); j++) { 19984 TObjectName columnName = new TObjectName(); 19985 if (resultColumn.getAliasClause() != null) { 19986 columnName.setString(resultColumn.getAliasClause() + "." + getColumnNameOnly( 19987 resultColumnFunction.getColumns().get(j).getName())); 19988 } else { 19989 columnName.setString(functionName + "." + getColumnNameOnly( 19990 resultColumnFunction.getColumns().get(j).getName())); 19991 } 19992 ResultColumn functionResultColumn = modelFactory.createResultColumn(function, 19993 columnName); 19994 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 19995 relationship.setTarget(new ResultColumnRelationshipElement(functionResultColumn)); 19996 relationship.addSource(new ResultColumnRelationshipElement( 19997 resultColumnFunction.getColumns().get(j))); 19998 } 19999 } 20000 else if (resultColumn.getExpr().getCaseExpression() != null) { 20001 function = modelFactory.createFunction(resultColumn.getExpr().getCaseExpression()); 20002 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20003 ((TCaseExpression) resultColumn.getExpr().getCaseExpression()).getWhenClauseItemList()); 20004 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20005 } 20006 } 20007 } 20008 return function; 20009 } 20010 } 20011 else if(functionObj instanceof TFunctionCall) { 20012 20013 } 20014 } 20015 20016 // BigQuery array_agg(table_alias) row-reference expansion 20017 if (functionObj.getFunctionType() == EFunctionType.array_agg_t 20018 && option.getVendor() == EDbVendor.dbvbigquery 20019 && functionObj.getArgs() != null 20020 && functionObj.getArgs().size() == 1) { 20021 20022 TExpression arg0 = functionObj.getArgs().getExpression(0); 20023 if (arg0 != null 20024 && arg0.getExpressionType() == EExpressionType.simple_object_name_t) { 20025 20026 TObjectName on = arg0.getObjectOperand(); 20027 if (isArrayAggRowReference(on)) { 20028 Function function = (Function) modelManager.getModel(functionCall); 20029 if (function == null) { 20030 function = modelFactory.createFunction((TFunctionCall) functionCall); 20031 } 20032 20033 // Only bind once (avoid duplicate processing when 20034 // createFunction is called from analyzeFunctionDataFlowRelation) 20035 if (function.getColumns() == null || function.getColumns().isEmpty()) { 20036 TTable srcTable = on.getSourceTable(); 20037 String tableAlias = srcTable.getAliasName() != null 20038 ? srcTable.getAliasName().toString() : null; 20039 20040 Table sourceTable = (Table) modelManager.getModel(srcTable); 20041 sourceTable.removeColumn(tableAlias); 20042 20043 // Collect inferred column names from ORDER BY (in function) 20044 // and GROUP BY (in enclosing SELECT). Excludes the table alias. 20045 List<TObjectName> inferredColumns = collectRowReferenceInferredColumns( 20046 functionObj, tableAlias); 20047 20048 // Create a single * function result column carrying star-link 20049 // metadata for the inferred columns and direct source edges 20050 // for * and each inferred column. 20051 createRowReferenceStarColumn(function, srcTable, inferredColumns); 20052 } 20053 20054 return function; 20055 } 20056 } 20057 } 20058 20059 if (functionObj.getFunctionType() == EFunctionType.array_t || functionObj.getFunctionType() == EFunctionType.array_agg_t) { 20060 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 20061 if(functionObj.getArgs()!=null) { 20062 if(functionObj.getArgs().getExpression(0).getSubQuery()!=null) { 20063 TSelectSqlStatement stmt = functionObj.getArgs().getExpression(0).getSubQuery(); 20064 analyzeSelectStmt(stmt); 20065 ResultSet resultset = (ResultSet) modelManager.getModel(stmt); 20066 for (int i = 0; i < resultset.getColumns().size(); i++) { 20067 ResultColumn sourceColumn = resultset.getColumns().get(i); 20068 TObjectName columnName = new TObjectName(); 20069 columnName.setString(sourceColumn.getName()); 20070 ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function, 20071 columnName); 20072 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 20073 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20074 relationship.addSource( 20075 new ResultColumnRelationshipElement(sourceColumn)); 20076 } 20077 return function; 20078 } 20079 else if (functionObj.getArgs().getExpression(0).getExpressionType() == EExpressionType.function_t) { 20080 Object functionTableModelObj = createFunction(functionObj.getArgs().getExpression(0).getFunctionCall()); 20081 if (functionTableModelObj instanceof ResultSet) { 20082 ResultSet resultset = (ResultSet) functionTableModelObj; 20083 for (int i = 0; i < resultset.getColumns().size(); i++) { 20084 ResultColumn sourceColumn = resultset.getColumns().get(i); 20085 TObjectName columnName = new TObjectName(); 20086 columnName.setString(sourceColumn.getName()); 20087 ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function, columnName); 20088 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 20089 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20090 relationship.addSource(new ResultColumnRelationshipElement(sourceColumn)); 20091 } 20092 return function; 20093 } 20094 } 20095 } 20096 } 20097 20098 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 20099 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20100 ((TFunctionCall) functionCall).getFunctionName()); 20101 if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) { 20102 // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP 20103 // COUNT特殊处理,不和参数关联 20104 if (option.isShowCountTableColumn()) { 20105 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20106 } 20107 } else { 20108 boolean isCustomFunction = analyzeCustomFunctionCall((TFunctionCall)functionCall); 20109// if(!isCustomFunction) 20110 { 20111 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20112 } 20113 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function)); 20114 if(functionTableModelObjs!=null) { 20115 for(Object functionTableModelObj: functionTableModelObjs) { 20116 if (functionTableModelObj instanceof ResultSet) { 20117 ResultSet functionTableModel = (ResultSet) functionTableModelObj; 20118 if (functionTableModel.getColumns() != null) { 20119 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 20120 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20121 relation.setEffectType(EffectType.select); 20122 relation.setTarget(new ResultColumnRelationshipElement(column)); 20123 relation.addSource(new ResultColumnRelationshipElement( 20124 functionTableModel.getColumns().get(j))); 20125 } 20126 } 20127 } 20128 } 20129 } 20130 } 20131 return function; 20132 } else if (functionCall instanceof TCaseExpression) { 20133 Function function = modelFactory.createFunction((TCaseExpression) functionCall); 20134 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20135 ((TCaseExpression) functionCall).getWhenClauseItemList()); 20136 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20137 return function; 20138 } else if (functionCall instanceof TObjectName) { 20139 Function function = modelFactory.createFunction((TObjectName) functionCall); 20140 TObjectName columnName = new TObjectName(); 20141 columnName.setString(function.getFunctionName()); 20142 ResultColumn column = modelFactory.createResultColumn(function, 20143 columnName); 20144 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20145 return function; 20146 } 20147 return null; 20148 } 20149 20150 protected String getIdentifiedFunctionName(Function function) { 20151 return DlineageUtil.getIdentifierNormalFunctionName(function.getFunctionName()); 20152 } 20153 20154 private boolean isConstantFunction(TObjectName functionName) { 20155 boolean result = CONSTANT_BUILTIN_FUNCTIONS.contains(functionName.toString().toUpperCase()); 20156 if (result) { 20157 return true; 20158 } 20159 return false; 20160 } 20161 20162 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TParseTreeNode gspObject) { 20163 List<TExpression> directExpressions = new ArrayList<TExpression>(); 20164 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 20165 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 20166 if (gspObject instanceof TFunctionCall) { 20167 TFunctionCall functionCall = (TFunctionCall) gspObject; 20168 getFunctionExpressions(directExpressions, indirectExpressions, functionCall); 20169 } else if (gspObject instanceof TCaseExpression) { 20170 TCaseExpression expr = (TCaseExpression) gspObject; 20171 TExpression inputExpr = expr.getInput_expr(); 20172 if (inputExpr != null) { 20173 if(option.isShowCaseWhenAsDirect()){ 20174 directExpressions.add(inputExpr); 20175 } 20176 else { 20177 conditionExpressions.add(inputExpr); 20178 } 20179 } 20180 TExpression defaultExpr = expr.getElse_expr(); 20181 if (defaultExpr != null) { 20182 directExpressions.add(defaultExpr); 20183 } 20184 TWhenClauseItemList list = expr.getWhenClauseItemList(); 20185 for (int i = 0; i < list.size(); i++) { 20186 TWhenClauseItem element = list.getWhenClauseItem(i); 20187 if(option.isShowCaseWhenAsDirect()){ 20188 directExpressions.add(element.getComparison_expr()); 20189 } 20190 else { 20191 conditionExpressions.add(element.getComparison_expr()); 20192 } 20193 directExpressions.add(element.getReturn_expr()); 20194 } 20195 } 20196 20197 for (int j = 0; j < directExpressions.size(); j++) { 20198 columnsInExpr visitor = new columnsInExpr(); 20199 directExpressions.get(j).inOrderTraverse(visitor); 20200 20201 List<TObjectName> objectNames = visitor.getObjectNames(); 20202 List<TParseTreeNode> functions = visitor.getFunctions(); 20203 20204 if (functions != null && !functions.isEmpty()) { 20205 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 20206 } 20207 20208 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 20209 if (subquerys != null && !subquerys.isEmpty()) { 20210 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 20211 } 20212 20213 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 20214 20215 List<TParseTreeNode> constants = visitor.getConstants(); 20216 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 20217 } 20218 20219 conditionExpressions.addAll(indirectExpressions); 20220 for (int j = 0; j < conditionExpressions.size(); j++) { 20221 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 20222 } 20223 } 20224 20225 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TCallStatement callStatment, int argumentIndex, Process process) { 20226 List<TExpression> directExpressions = new ArrayList<TExpression>(); 20227 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 20228 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 20229 20230 getFunctionExpressions(directExpressions, indirectExpressions, callStatment, argumentIndex); 20231 20232 for (int j = 0; j < directExpressions.size(); j++) { 20233 columnsInExpr visitor = new columnsInExpr(); 20234 directExpressions.get(j).inOrderTraverse(visitor); 20235 20236 List<TObjectName> objectNames = visitor.getObjectNames(); 20237 List<TParseTreeNode> functions = visitor.getFunctions(); 20238 20239 if (functions != null && !functions.isEmpty()) { 20240 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 20241 } 20242 20243 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 20244 if (subquerys != null && !subquerys.isEmpty()) { 20245 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 20246 } 20247 20248 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 20249 if (relation != null) { 20250 relation.setProcess(process); 20251 } 20252 20253 List<TParseTreeNode> constants = visitor.getConstants(); 20254 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 20255 } 20256 20257 conditionExpressions.addAll(indirectExpressions); 20258 for (int j = 0; j < conditionExpressions.size(); j++) { 20259 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 20260 } 20261 } 20262 20263 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TFunctionCall functionCall, int argumentIndex, Process process) { 20264 List<TExpression> directExpressions = new ArrayList<TExpression>(); 20265 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 20266 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 20267 20268 getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentIndex); 20269 20270 for (int j = 0; j < directExpressions.size(); j++) { 20271 columnsInExpr visitor = new columnsInExpr(); 20272 directExpressions.get(j).inOrderTraverse(visitor); 20273 20274 List<TObjectName> objectNames = visitor.getObjectNames(); 20275 List<TParseTreeNode> functions = visitor.getFunctions(); 20276 20277 if (functions != null && !functions.isEmpty()) { 20278 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 20279 } 20280 20281 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 20282 if (subquerys != null && !subquerys.isEmpty()) { 20283 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 20284 } 20285 20286 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 20287 if (relation != null) { 20288 relation.setProcess(process); 20289 } 20290 20291 List<TParseTreeNode> constants = visitor.getConstants(); 20292 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 20293 } 20294 20295 conditionExpressions.addAll(indirectExpressions); 20296 for (int j = 0; j < conditionExpressions.size(); j++) { 20297 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 20298 } 20299 } 20300 20301 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TMssqlExecute functionCall, String argumentName, int argumentIndex, Process process) { 20302 List<TExpression> directExpressions = new ArrayList<TExpression>(); 20303 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 20304 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 20305 20306 getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentName, argumentIndex); 20307 20308 for (int j = 0; j < directExpressions.size(); j++) { 20309 columnsInExpr visitor = new columnsInExpr(); 20310 directExpressions.get(j).inOrderTraverse(visitor); 20311 20312 List<TObjectName> objectNames = visitor.getObjectNames(); 20313 List<TParseTreeNode> functions = visitor.getFunctions(); 20314 20315 if (functions != null && !functions.isEmpty()) { 20316 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 20317 } 20318 20319 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 20320 if (subquerys != null && !subquerys.isEmpty()) { 20321 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 20322 } 20323 20324 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 20325 if (relation != null) { 20326 relation.setProcess(process); 20327 } 20328 20329 List<TParseTreeNode> constants = visitor.getConstants(); 20330 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 20331 } 20332 20333 conditionExpressions.addAll(indirectExpressions); 20334 for (int j = 0; j < conditionExpressions.size(); j++) { 20335 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 20336 } 20337 } 20338 20339 20340 private static void addResultColumnListExpressions( 20341 TResultColumnList list, List<TExpression> target) { 20342 if (list == null) return; 20343 for (int k = 0; k < list.size(); k++) { 20344 TExpression e = list.getResultColumn(k).getExpr(); 20345 if (e != null) target.add(e); 20346 } 20347 } 20348 20349 private static void addPassingClauseExpressions( 20350 TFunctionCall fc, List<TExpression> target) { 20351 TResultColumnList list = null; 20352 if (fc.getXmlPassingClause() != null 20353 && fc.getXmlPassingClause().getPassingList() != null) { 20354 list = fc.getXmlPassingClause().getPassingList(); 20355 } else if (fc.getPassingClause() != null 20356 && fc.getPassingClause().getPassingList() != null) { 20357 list = fc.getPassingClause().getPassingList(); 20358 } 20359 addResultColumnListExpressions(list, target); 20360 } 20361 20362 private void collectOracleXmlFunctionExpressions( 20363 TFunctionCall fc, 20364 List<TExpression> direct, 20365 List<TExpression> indirect) { 20366 20367 if (option.getVendor() != EDbVendor.dbvoracle) return; 20368 20369 // XMLELEMENT: value exprs + XMLATTRIBUTES exprs (direct) 20370 addResultColumnListExpressions(fc.getXMLElementValueExprList(), direct); 20371 if (fc.getXMLAttributesClause() != null) { 20372 addResultColumnListExpressions( 20373 fc.getXMLAttributesClause().getValueExprList(), direct); 20374 } 20375 20376 // XMLFOREST (direct) 20377 addResultColumnListExpressions(fc.getXMLForestValueList(), direct); 20378 20379 // EXTRACT(XML) — AST-shape disambiguation (V3) 20380 // XML form populates getXMLType_Instance(); scalar EXTRACT(YEAR FROM d) does not. 20381 if (fc.getXMLType_Instance() != null) { 20382 direct.add(fc.getXMLType_Instance()); 20383 } 20384 20385 String name = fc.getFunctionName() == null 20386 ? "" : fc.getFunctionName().toString().toUpperCase(); 20387 20388 // XMLEXISTS indirect (filter) from PASSING expressions 20389 if ("XMLEXISTS".equals(name)) { 20390 addPassingClauseExpressions(fc, indirect); 20391 } 20392 20393 // XMLAGG / SYS_XMLAGG ORDER BY → indirect 20394 if (("XMLAGG".equals(name) || "SYS_XMLAGG".equals(name)) 20395 && fc.getSortClause() != null) { 20396 TOrderByItemList orderByList = fc.getSortClause().getItems(); 20397 if (orderByList != null) { 20398 for (int k = 0; k < orderByList.size(); k++) { 20399 TExpression e = orderByList.getOrderByItem(k).getSortKey(); 20400 if (e != null) indirect.add(e); 20401 } 20402 } 20403 } 20404 20405 // DELIBERATELY NOT HARVESTED (metadata, not data): 20406 // fc.getTypeExpression() — target type for XMLCAST 20407 // fc.getXMLElementNameExpr() — element tag identifier 20408 // XPath / XQuery literal strings that appear as function args 20409 // datatype / format / style tokens 20410 } 20411 20412 private void collectArrayAggOrderByExpressions( 20413 TFunctionCall fc, 20414 List<TExpression> direct, 20415 List<TExpression> indirect) { 20416 if (fc.getFunctionType() != EFunctionType.array_agg_t) return; 20417 20418 TOrderByItemList items = null; 20419 if (fc.getSortClause() != null) items = fc.getSortClause().getItems(); 20420 if (items == null || items.size() == 0) { 20421 items = fc.getOrderByList(); 20422 } 20423 if (items == null) return; 20424 20425 // Resolve source tables for ORDER BY columns that the parser 20426 // doesn't link (they're inside a function call, outside the 20427 // resolver's normal scope) 20428 TTable fallbackTable = null; 20429 if (!stmtStack.isEmpty() && stmtStack.peek() instanceof TSelectSqlStatement) { 20430 TTableList tables = ((TSelectSqlStatement) stmtStack.peek()).tables; 20431 if (tables != null && tables.size() > 0) { 20432 fallbackTable = tables.getTable(0); 20433 } 20434 } 20435 20436 for (int k = 0; k < items.size(); k++) { 20437 TExpression e = items.getOrderByItem(k).getSortKey(); 20438 if (e != null) { 20439 if (fallbackTable != null 20440 && e.getExpressionType() == EExpressionType.simple_object_name_t 20441 && e.getObjectOperand() != null 20442 && e.getObjectOperand().getSourceTable() == null) { 20443 e.getObjectOperand().setSourceTable(fallbackTable); 20444 } 20445 direct.add(e); 20446 } 20447 } 20448 } 20449 20450 private boolean isArrayAggRowReference(TObjectName on) { 20451 if (on == null) return false; 20452 TTable src = on.getSourceTable(); 20453 if (src == null) return false; 20454 20455 String nm = DlineageUtil.getColumnName(on); 20456 if (nm == null || nm.isEmpty()) return false; 20457 20458 // Check if identifier text matches the table alias or table name 20459 boolean matchesAlias = 20460 (src.getAliasName() != null 20461 && src.getAliasName().toString().equalsIgnoreCase(nm)) 20462 || (src.getTableName() != null 20463 && src.getTableName().toString().equalsIgnoreCase(nm)); 20464 return matchesAlias; 20465 } 20466 20467 /** 20468 * Collects column names inferred from a row-reference array_agg: 20469 * - ORDER BY keys inside the function call 20470 * - GROUP BY keys in the enclosing SELECT 20471 * Excludes the table alias itself (so `original` in `array_agg(original)` 20472 * does not leak into the column list). 20473 */ 20474 private List<TObjectName> collectRowReferenceInferredColumns( 20475 TFunctionCall functionCall, String tableAlias) { 20476 List<TObjectName> columns = new ArrayList<TObjectName>(); 20477 20478 TOrderByItemList orderItems = null; 20479 if (functionCall.getSortClause() != null) { 20480 orderItems = functionCall.getSortClause().getItems(); 20481 } 20482 if (orderItems == null || orderItems.size() == 0) { 20483 orderItems = functionCall.getOrderByList(); 20484 } 20485 if (orderItems != null) { 20486 for (int k = 0; k < orderItems.size(); k++) { 20487 TExpression sortKey = orderItems.getOrderByItem(k).getSortKey(); 20488 collectInferredColumn(sortKey, tableAlias, columns); 20489 } 20490 } 20491 20492 if (!stmtStack.isEmpty() && stmtStack.peek() instanceof TSelectSqlStatement) { 20493 TSelectSqlStatement select = (TSelectSqlStatement) stmtStack.peek(); 20494 if (select.getGroupByClause() != null) { 20495 TGroupByItemList groupByList = select.getGroupByClause().getItems(); 20496 for (int k = 0; k < groupByList.size(); k++) { 20497 TExpression expr = groupByList.getGroupByItem(k).getExpr(); 20498 collectInferredColumn(expr, tableAlias, columns); 20499 } 20500 } 20501 } 20502 return columns; 20503 } 20504 20505 private void collectInferredColumn(TExpression expr, String tableAlias, 20506 List<TObjectName> columns) { 20507 if (expr == null) return; 20508 if (expr.getExpressionType() != EExpressionType.simple_object_name_t) return; 20509 if (expr.getObjectOperand() == null) return; 20510 String colName = DlineageUtil.getColumnName(expr.getObjectOperand()); 20511 if (colName == null || colName.isEmpty()) return; 20512 if (tableAlias != null && tableAlias.equalsIgnoreCase(colName)) return; 20513 if(!columns.contains(expr.getObjectOperand())) { 20514 columns.add(expr.getObjectOperand()); 20515 } 20516 } 20517 20518 /** 20519 * Creates a `*` FunctionResultColumn plus one FunctionResultColumn per 20520 * inferred column. Each column gets its own source-edge back to 20521 * the source table (source.* -> function.*, source.id -> function.id, etc). 20522 * 20523 * Downstream, the `*` column collects all three edges into the inner 20524 * `unique` ResultColumn, and post-processing (rewriteArrayAggRowReferenceTargets) 20525 * splits the collapsed CTAS relation into one per column. 20526 */ 20527 private void createRowReferenceStarColumn(Function function, TTable src, 20528 List<TObjectName> inferredColumns) { 20529 Object tableModel = modelManager.getModel(src); 20530 20531 // Create function.* and bind source.* -> function.* 20532 TObjectName starName = new TObjectName(); 20533 starName.setString("*"); 20534 ResultColumn starColumn = modelFactory.createFunctionResultColumn(function, starName); 20535 starColumn.setStruct(true); 20536 starColumn.setShowStar(true); 20537 20538 if (tableModel instanceof Table) { 20539 Table sourceTable = (Table) tableModel; 20540 TableColumn sourceCol = findOrCreateTableColumn(sourceTable, "*"); 20541 20542 for (TObjectName colName : inferredColumns) { 20543 TableColumn tableColumn = modelFactory.createTableColumn(sourceTable, colName, false); 20544 if (tableColumn != null) { 20545 //order by and group by fdr relation 20546 AbstractRelationship relation = modelFactory.createImpactRelation(); 20547 relation.setEffectType(EffectType.function); 20548 relation.setTarget(new ResultColumnRelationshipElement(starColumn)); 20549 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20550 20551 // star column fdd relation 20552 relation = modelFactory.createDataFlowRelation(); 20553 relation.setEffectType(EffectType.function); 20554 relation.setTarget(new ResultColumnRelationshipElement(starColumn)); 20555 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20556 } 20557 } 20558 20559 20560 if (sourceCol != null) { 20561 DataFlowRelationship rel = modelFactory.createDataFlowRelation(); 20562 rel.setEffectType(EffectType.function); 20563 rel.setTarget(new ResultColumnRelationshipElement(starColumn)); 20564 rel.addSource(new TableColumnRelationshipElement(sourceCol)); 20565 } 20566 20567 } else if (tableModel instanceof ResultSet) { 20568 ResultSet sourceRS = (ResultSet) tableModel; 20569 ResultColumn sourceCol = findOrCreateResultColumn(sourceRS, "*"); 20570 for (TObjectName colName : inferredColumns) { 20571 sourceCol.bindStarLinkColumn(colName); 20572 } 20573 20574 if (sourceCol != null) { 20575 DataFlowRelationship rel = modelFactory.createDataFlowRelation(); 20576 rel.setEffectType(EffectType.function); 20577 rel.setTarget(new ResultColumnRelationshipElement(starColumn)); 20578 rel.addSource(new ResultColumnRelationshipElement(sourceCol)); 20579 } 20580 } 20581 } 20582 20583 /** 20584 * Builds the Function lineage model for a structured-dataflow descriptor. 20585 * Creates per-field FunctionResultColumns and links each to an exact 20586 * structured source TableColumn (e.g. {@code nodes[*].key}). Returns the 20587 * Function on success; returns {@code null} when the source column cannot 20588 * be resolved so the caller falls back to existing function lineage. 20589 */ 20590 private Function createStructuredDataflowFunction(StructuredDataflowDescriptor desc) { 20591 TParseTreeNode syntaxNode = desc.getSyntaxNode(); 20592 if (!(syntaxNode instanceof TFunctionCall)) { 20593 return null; 20594 } 20595 TFunctionCall fnCall = (TFunctionCall) syntaxNode; 20596 20597 Function function = null; 20598 Object existing = modelManager.getModel(fnCall); 20599 if (existing instanceof Function) { 20600 function = (Function) existing; 20601 } 20602 boolean alreadyBuilt = function != null 20603 && function.getColumns() != null 20604 && !function.getColumns().isEmpty(); 20605 if (alreadyBuilt) { 20606 return function; 20607 } 20608 if (function == null) { 20609 function = modelFactory.createFunction(fnCall); 20610 } 20611 20612 StructuredValueSource src = desc.getSource(); 20613 TObjectName sourceColumn = src.getSourceColumn(); 20614 TTable srcTable = sourceColumn != null ? sourceColumn.getSourceTable() : null; 20615 Object srcTableModel = srcTable != null ? modelManager.getModel(srcTable) : null; 20616 if (!(srcTableModel instanceof Table)) { 20617 return null; 20618 } 20619 Table sourceTable = (Table) srcTableModel; 20620 20621 for (StructuredFieldBinding fb : desc.getFieldBindings()) { 20622 String pathDisplay = fb.getSourcePath().toDisplayString(); 20623 TableColumn pathColumn = findOrCreateStructuredPathColumn(sourceTable, pathDisplay); 20624 if (pathColumn == null) { 20625 continue; 20626 } 20627 20628 TObjectName fieldName = new TObjectName(); 20629 fieldName.setString(fb.getOutputFieldName()); 20630 ResultColumn fnResult = modelFactory.createFunctionResultColumn(function, fieldName); 20631 20632 DataFlowRelationship rel = modelFactory.createDataFlowRelation(); 20633 rel.setEffectType(EffectType.function); 20634 rel.setTarget(new ResultColumnRelationshipElement(fnResult)); 20635 rel.addSource(new TableColumnRelationshipElement(pathColumn)); 20636 } 20637 return function; 20638 } 20639 20640 /** 20641 * Resolve a struct-field-style outer reference ({@code structAlias.field} 20642 * or {@code relAlias.structAlias.field}) against in-scope subquery 20643 * QueryTables that hold a struct-bearing result column. When found, 20644 * append a relation source pointing at the function's field result 20645 * column so the exact source path (e.g. {@code nodes[*].key}) is 20646 * preserved through the outer projection. Returns {@code true} when 20647 * the reference was bound and the caller should skip orphan-column 20648 * fallback. 20649 */ 20650 private boolean tryAppendStructuredFieldRelation(DataFlowRelationship relation, 20651 TObjectName columnName, TTableList tableList) { 20652 if (relation == null || columnName == null || tableList == null) { 20653 return false; 20654 } 20655 String fullText = columnName.toString(); 20656 if (fullText == null) return false; 20657 int firstDot = fullText.indexOf('.'); 20658 if (firstDot < 0) return false; 20659 20660 String structAlias; 20661 String fieldName; 20662 int lastDot = fullText.lastIndexOf('.'); 20663 if (firstDot == lastDot) { 20664 structAlias = fullText.substring(0, firstDot); 20665 fieldName = fullText.substring(firstDot + 1); 20666 } else { 20667 structAlias = fullText.substring(firstDot + 1, lastDot); 20668 fieldName = fullText.substring(lastDot + 1); 20669 } 20670 if (structAlias == null || structAlias.isEmpty()) return false; 20671 if (fieldName == null || fieldName.isEmpty()) return false; 20672 20673 for (int i = 0; i < tableList.size(); i++) { 20674 TTable tt = tableList.getTable(i); 20675 if (tt == null) continue; 20676 Object tm = modelManager.getModel(tt); 20677 if (!(tm instanceof QueryTable)) continue; 20678 QueryTable qt = (QueryTable) tm; 20679 if (qt.getColumns() == null) continue; 20680 for (ResultColumn rc : qt.getColumns()) { 20681 if (rc == null || rc.getName() == null) continue; 20682 if (!structAlias.equalsIgnoreCase(rc.getName())) continue; 20683 ResultColumn fieldColumn = findStructuredFieldColumn(rc, fieldName); 20684 if (fieldColumn != null) { 20685 relation.addSource(new ResultColumnRelationshipElement(fieldColumn)); 20686 return true; 20687 } 20688 } 20689 } 20690 return false; 20691 } 20692 20693 /** 20694 * Given a QueryTable result column that aliases a structured generator 20695 * (e.g. {@code nodes1} backed by Spark {@code explode(from_json(...))}), 20696 * locate the FunctionResultColumn named {@code fieldName}. The Function 20697 * model is discovered by walking the existing data-flow relations whose 20698 * target is the alias column. 20699 */ 20700 private ResultColumn findStructuredFieldColumn(ResultColumn aliasColumn, String fieldName) { 20701 if (aliasColumn == null || fieldName == null) return null; 20702 Relationship[] rels = modelManager.getRelations(); 20703 if (rels == null) return null; 20704 String normalField = fieldName.trim(); 20705 for (Relationship r : rels) { 20706 if (!(r instanceof DataFlowRelationship)) continue; 20707 DataFlowRelationship dfr = (DataFlowRelationship) r; 20708 if (dfr.getTarget() == null) continue; 20709 if (!(dfr.getTarget().getElement() == aliasColumn)) continue; 20710 if (dfr.getSources() == null) continue; 20711 for (RelationshipElement<?> se : dfr.getSources()) { 20712 Object srcElement = se.getElement(); 20713 if (!(srcElement instanceof ResultColumn)) continue; 20714 ResultColumn src = (ResultColumn) srcElement; 20715 if (normalField.equalsIgnoreCase(src.getName())) { 20716 return src; 20717 } 20718 } 20719 } 20720 return null; 20721 } 20722 20723 /** 20724 * Find-or-create a TableColumn carrying a structured display path 20725 * (e.g. {@code nodes[*].key}) on the given source table. Unlike the 20726 * standard {@link #findOrCreateTableColumn(Table, String)}, this does 20727 * not treat the dotted/bracketed text as a schema-qualified name; 20728 * the entire path is used as the column display, so existing flat 20729 * columns named after the leaf field (e.g. {@code key}) do not 20730 * collide with structured-path columns. 20731 */ 20732 private TableColumn findOrCreateStructuredPathColumn(Table table, String pathDisplay) { 20733 if (table == null || pathDisplay == null || pathDisplay.isEmpty()) return null; 20734 for (TableColumn tc : table.getColumns()) { 20735 if (pathDisplay.equalsIgnoreCase(tc.getName())) { 20736 return tc; 20737 } 20738 } 20739 return new TableColumn(table, pathDisplay); 20740 } 20741 20742 private TableColumn findOrCreateTableColumn(Table table, String colName) { 20743 String normalName = DlineageUtil.getIdentifierNormalColumnName(colName); 20744 for (TableColumn tc : table.getColumns()) { 20745 if ("*".equals(colName) && "*".equals(tc.getName())) return tc; 20746 if (DlineageUtil.compareColumnIdentifier(tc.getName(), normalName)) return tc; 20747 } 20748 TObjectName obj = new TObjectName(); 20749 obj.setString(colName); 20750 return modelFactory.createTableColumn(table, obj, "*".equals(colName)); 20751 } 20752 20753 private ResultColumn findOrCreateResultColumn(ResultSet resultSet, String colName) { 20754 String normalName = DlineageUtil.getIdentifierNormalColumnName(colName); 20755 for (ResultColumn rc : resultSet.getColumns()) { 20756 if ("*".equals(colName) && "*".equals(rc.getName())) return rc; 20757 if (DlineageUtil.compareColumnIdentifier(rc.getName(), normalName)) return rc; 20758 } 20759 TObjectName obj = new TObjectName(); 20760 obj.setString(colName); 20761 return modelFactory.createResultColumn(resultSet, obj); 20762 } 20763 20764 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 20765 TFunctionCall functionCall) { 20766 if (functionCall.getArgs() != null) { 20767 for (int k = 0; k < functionCall.getArgs().size(); k++) { 20768 TExpression expr = functionCall.getArgs().getExpression(k); 20769 if(FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), k)) { 20770 directExpressions.add(expr); 20771 } 20772 if(FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), k)) { 20773 if("DECODE".equalsIgnoreCase(functionCall.getFunctionName().toString()) && option.getVendor() == EDbVendor.dbvoracle) { 20774 if(option.isShowCaseWhenAsDirect()) { 20775 directExpressions.add(expr); 20776 continue; 20777 } 20778 } 20779 indirectExpressions.add(expr); 20780 } 20781 } 20782 } 20783 collectOracleXmlFunctionExpressions(functionCall, directExpressions, indirectExpressions); 20784 collectArrayAggOrderByExpressions(functionCall, directExpressions, indirectExpressions); 20785 if (functionCall.getTrimArgument() != null) { 20786 TTrimArgument args = functionCall.getTrimArgument(); 20787 TExpression expr = args.getStringExpression(); 20788 if (expr != null) { 20789 directExpressions.add(expr); 20790 } 20791 expr = args.getTrimCharacter(); 20792 if (expr != null) { 20793 directExpressions.add(expr); 20794 } 20795 } 20796 20797 if (functionCall.getAgainstExpr() != null) { 20798 directExpressions.add(functionCall.getAgainstExpr()); 20799 } 20800// if (functionCall.getBetweenExpr() != null) { 20801// directExpressions.add(functionCall.getBetweenExpr()); 20802// } 20803 if (functionCall.getExpr1() != null) { 20804 directExpressions.add(functionCall.getExpr1()); 20805 } 20806 if (functionCall.getExpr2() != null) { 20807 directExpressions.add(functionCall.getExpr2()); 20808 } 20809 if (functionCall.getExpr3() != null) { 20810 directExpressions.add(functionCall.getExpr3()); 20811 } 20812 if (functionCall.getParameter() != null) { 20813 directExpressions.add(functionCall.getParameter()); 20814 } 20815 if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getPartitionClause() != null) { 20816 TExpressionList args = functionCall.getWindowDef().getPartitionClause().getExpressionList(); 20817 if (args != null) { 20818 for (int k = 0; k < args.size(); k++) { 20819 TExpression expr = args.getExpression(k); 20820 if (expr != null) { 20821 indirectExpressions.add(expr); 20822 } 20823 } 20824 } 20825 } 20826 if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getOrderBy() != null) { 20827 TOrderByItemList orderByList = functionCall.getWindowDef().getOrderBy().getItems(); 20828 for (int i = 0; i < orderByList.size(); i++) { 20829 TOrderByItem element = orderByList.getOrderByItem(i); 20830 TExpression expression = element.getSortKey(); 20831 indirectExpressions.add(expression); 20832 } 20833 } 20834 if (functionCall.getWithinGroup() != null && functionCall.getWithinGroup().getOrderBy() != null) { 20835 TOrderByItemList orderByList = functionCall.getWithinGroup().getOrderBy().getItems(); 20836 for (int i = 0; i < orderByList.size(); i++) { 20837 TOrderByItem element = orderByList.getOrderByItem(i); 20838 TExpression expression = element.getSortKey(); 20839 indirectExpressions.add(expression); 20840 } 20841 } 20842 if (functionCall.getCallTarget() != null) { 20843 directExpressions.add(functionCall.getCallTarget().getExpr()); 20844 } 20845 if (functionCall.getFieldValues() != null) { 20846 for (int k = 0; k < functionCall.getFieldValues().size(); k++) { 20847 TExpression expr = functionCall.getFieldValues().getResultColumn(k).getExpr(); 20848 directExpressions.add(expr); 20849 } 20850 } 20851 if (functionCall instanceof TJsonObjectFunction) { 20852 TJsonObjectFunction jsonObject = (TJsonObjectFunction)functionCall; 20853 for (int k = 0; k < jsonObject.getKeyValues().size(); k++) { 20854 TExpression expr = jsonObject.getKeyValues().get(k).getValue(); 20855 directExpressions.add(expr); 20856 } 20857 } 20858 if (functionCall.getGroupConcatParam() != null) { 20859 for (int k = 0; k < functionCall.getGroupConcatParam().getExprList().size(); k++) { 20860 TExpression expr = functionCall.getGroupConcatParam().getExprList().getExpression(k); 20861 directExpressions.add(expr); 20862 } 20863 } 20864 } 20865 20866 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 20867 TFunctionCall functionCall, int argumentIndex) { 20868 if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) { 20869 TExpression expr = functionCall.getArgs().getExpression(argumentIndex); 20870 if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) { 20871 directExpressions.add(expr); 20872 } 20873 if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) { 20874 indirectExpressions.add(expr); 20875 } 20876 } 20877 } 20878 20879 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 20880 TCallStatement functionCall, int argumentIndex) { 20881 if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) { 20882 TExpression expr = functionCall.getArgs().getExpression(argumentIndex); 20883 if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getRoutineName().toString(), 20884 functionCall.getArgs().size(), argumentIndex)) { 20885 directExpressions.add(expr); 20886 } 20887 if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getRoutineName().toString(), 20888 functionCall.getArgs().size(), argumentIndex)) { 20889 indirectExpressions.add(expr); 20890 } 20891 } 20892 } 20893 20894 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 20895 TMssqlExecute functionCall, String argumentName, int argumentIndex) { 20896 if (functionCall.getParameters() != null) { 20897 for (int i = 0; i < functionCall.getParameters().size(); i++) { 20898 TExecParameter param = functionCall.getParameters().getExecParameter(i); 20899 if (param.getParameterName() != null) { 20900 if (DlineageUtil.compareColumnIdentifier(param.getParameterName().toString(), argumentName)) { 20901 TExpression expr = param.getParameterValue(); 20902 directExpressions.add(expr); 20903 } 20904 } else if (i == argumentIndex) { 20905 TExpression expr = param.getParameterValue(); 20906 directExpressions.add(expr); 20907 } 20908 } 20909 } 20910 } 20911 20912 private void analyzeJoin(TJoin join, EffectType effectType) { 20913 if (join.getJoinItems() != null) { 20914 for (int j = 0; j < join.getJoinItems().size(); j++) { 20915 TJoinItem joinItem = join.getJoinItems().getJoinItem(j); 20916 TExpression expr = joinItem.getOnCondition(); 20917 if (expr != null) { 20918 analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on, effectType); 20919 } 20920 } 20921 } 20922 20923 if (join.getJoin() != null) { 20924 analyzeJoin(join.getJoin(), effectType); 20925 } 20926 } 20927 20928 private TSelectSqlStatement getParentSetSelectStmt(TSelectSqlStatement stmt) { 20929 TCustomSqlStatement parent = stmt.getParentStmt(); 20930 if (parent == null) 20931 return null; 20932 if (parent.getStatements() != null) { 20933 for (int i = 0; i < parent.getStatements().size(); i++) { 20934 TCustomSqlStatement temp = parent.getStatements().get(i); 20935 if (temp instanceof TSelectSqlStatement) { 20936 TSelectSqlStatement select = (TSelectSqlStatement) temp; 20937 if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt) 20938 return select; 20939 } 20940 } 20941 } 20942 if (parent instanceof TSelectSqlStatement) { 20943 TSelectSqlStatement select = (TSelectSqlStatement) parent; 20944 if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt) 20945 return select; 20946 } 20947 return null; 20948 } 20949 20950 private void createSelectSetResultColumns(SelectSetResultSet resultSet, TSelectSqlStatement stmt) { 20951 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 20952 createSelectSetResultColumns(resultSet, stmt.getLeftStmt()); 20953 } else { 20954 TResultColumnList columnList = stmt.getResultColumnList(); 20955 ResultSet subqueryResultSet = (ResultSet) modelManager.getModel(columnList); 20956 if(subqueryResultSet!=null && subqueryResultSet.isDetermined()) { 20957 for (int j = 0; j < subqueryResultSet.getColumns().size(); j++) { 20958 ResultColumn tableColumn = subqueryResultSet.getColumns().get(j); 20959 if (tableColumn.getRefColumnName() != null) { 20960 TObjectName columnName = new TObjectName(); 20961 columnName.setString(tableColumn.getRefColumnName()); 20962 modelFactory.createDeterminedResultColumn( 20963 resultSet, columnName); 20964 } else { 20965 TObjectName columnName = new TObjectName(); 20966 columnName.setString(tableColumn.getName()); 20967 modelFactory.createDeterminedResultColumn( 20968 resultSet, columnName); 20969 } 20970 } 20971 resultSet.setDetermined(true); 20972 return; 20973 } 20974 20975 boolean isDetermined = true; 20976 for (int i = 0; i < columnList.size(); i++) { 20977 TResultColumn column = columnList.getResultColumn(i); 20978 20979 if ("*".equals(column.getColumnNameOnly())) { 20980 TObjectName columnObject = column.getFieldAttr(); 20981 TTable sourceTable = columnObject.getSourceTable(); 20982 if (sourceTable != null) { 20983 Object tableModel = modelManager.getModel(sourceTable); 20984 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 20985 Table table = (Table) tableModel; 20986 for (int j = 0; j < table.getColumns().size(); j++) { 20987 TableColumn tableColumn = table.getColumns().get(j); 20988 if (column.getExceptColumnList() != null) { 20989 boolean except = false; 20990 for (TObjectName objectName : column.getExceptColumnList()) { 20991 if (getColumnName(objectName.toString()) 20992 .equals(getColumnName(tableColumn.getName()))) { 20993 except = true; 20994 break; 20995 } 20996 } 20997 if (!except && tableColumn.isStruct()) { 20998 List<String> names = SQLUtil 20999 .parseNames(tableColumn.getName()); 21000 for (String name : names) { 21001 for (TObjectName objectName : column 21002 .getExceptColumnList()) { 21003 if (getColumnName(objectName.toString()) 21004 .equals(getColumnName(name))) { 21005 except = true; 21006 break; 21007 } 21008 } 21009 if (except) { 21010 break; 21011 } 21012 } 21013 } 21014 if (except) { 21015 continue; 21016 } 21017 } 21018 TObjectName columnName = new TObjectName(); 21019 columnName.setString(tableColumn.getName()); 21020 ResultColumn resultColumn = modelFactory.createResultColumn( 21021 resultSet, columnName); 21022 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 21023 relation.setEffectType(EffectType.select); 21024 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 21025 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 21026 } 21027 continue; 21028 } else if (tableModel instanceof ResultSet 21029 && ((ResultSet) tableModel).isDetermined()) { 21030 ResultSet table = (ResultSet) tableModel; 21031 for (int j = 0; j < table.getColumns().size(); j++) { 21032 ResultColumn tableColumn = table.getColumns().get(j); 21033 if (column.getExceptColumnList() != null) { 21034 boolean except = false; 21035 for (TObjectName objectName : column.getExceptColumnList()) { 21036 if (getColumnName(objectName.toString()) 21037 .equals(getColumnName(tableColumn.getName()))) { 21038 except = true; 21039 break; 21040 } 21041 } 21042 if (!except && tableColumn.isStruct()) { 21043 List<String> names = SQLUtil 21044 .parseNames(tableColumn.getName()); 21045 for (String name : names) { 21046 for (TObjectName objectName : column 21047 .getExceptColumnList()) { 21048 if (getColumnName(objectName.toString()) 21049 .equals(getColumnName(name))) { 21050 except = true; 21051 break; 21052 } 21053 } 21054 if (except) { 21055 break; 21056 } 21057 } 21058 } 21059 if (except) { 21060 continue; 21061 } 21062 } 21063 if (tableColumn.getRefColumnName() != null) { 21064 TObjectName columnName = new TObjectName(); 21065 columnName.setString(tableColumn.getRefColumnName()); 21066 ResultColumn resultColumn = modelFactory.createResultColumn( 21067 resultSet, columnName); 21068 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 21069 relation.setEffectType(EffectType.select); 21070 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 21071 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 21072 } else { 21073 TObjectName columnName = new TObjectName(); 21074 columnName.setString(tableColumn.getName()); 21075 ResultColumn resultColumn = modelFactory.createResultColumn( 21076 resultSet, columnName); 21077 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 21078 relation.setEffectType(EffectType.select); 21079 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 21080 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 21081 } 21082 } 21083 continue; 21084 } 21085 else { 21086 isDetermined = false; 21087 } 21088 } 21089 } 21090 21091 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i); 21092 21093 if (resultColumn.getColumnObject() instanceof TResultColumn) { 21094 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 21095 if (columnObject.getFieldAttr() != null) { 21096 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 21097 TObjectName fieldAttr = columnObject.getFieldAttr(); 21098 TTable sourceTable = fieldAttr.getSourceTable(); 21099 if (fieldAttr.getTableToken() != null && sourceTable != null) { 21100 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 21101 for (int j = 0; j < columns.length; j++) { 21102 TObjectName columnName = columns[j]; 21103 if (columnName == null) { 21104 continue; 21105 } 21106 if ("*".equals(getColumnName(columnName))) { 21107 continue; 21108 } 21109 resultColumn.bindStarLinkColumn(columnName); 21110 } 21111 21112 if (modelManager.getModel(sourceTable) instanceof Table) { 21113 Table tableModel = (Table) modelManager.getModel(sourceTable); 21114 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 21115 for (int z = 0; z < tableModel.getColumns().size(); z++) { 21116 if ("*".equals( 21117 getColumnName(tableModel.getColumns().get(z).getColumnObject()))) { 21118 continue; 21119 } 21120 resultColumn.bindStarLinkColumn( 21121 tableModel.getColumns().get(z).getColumnObject()); 21122 } 21123 } 21124 } else if (modelManager.getModel(sourceTable) instanceof QueryTable) { 21125 QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable); 21126 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 21127 for (ResultColumn item : tableModel.getColumns()) { 21128 if (item.hasStarLinkColumn()) { 21129 for (TObjectName starLinkColumn : item.getStarLinkColumnList()) { 21130 if ("*".equals(getColumnName(starLinkColumn))) { 21131 continue; 21132 } 21133 resultColumn.bindStarLinkColumn(starLinkColumn); 21134 } 21135 } else if (item.getColumnObject() instanceof TObjectName) { 21136 TObjectName starLinkColumn = (TObjectName) item.getColumnObject(); 21137 if ("*".equals(getColumnName(starLinkColumn))) { 21138 continue; 21139 } 21140 resultColumn.bindStarLinkColumn(starLinkColumn); 21141 } 21142 } 21143 } 21144 } 21145 21146 } else { 21147 TTableList tables = stmt.getTables(); 21148 for (int k = 0; k < tables.size(); k++) { 21149 TTable tableElement = tables.getTable(k); 21150 TObjectName[] columns = modelManager.getTableColumns(tableElement); 21151 for (int j = 0; j < columns.length; j++) { 21152 TObjectName columnName = columns[j]; 21153 if (columnName == null) { 21154 continue; 21155 } 21156 if ("*".equals(getColumnName(columnName))) { 21157 if (modelManager.getModel(tableElement) instanceof Table) { 21158 Table tableModel = (Table) modelManager.getModel(tableElement); 21159 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 21160 for (int z = 0; z < tableModel.getColumns().size(); z++) { 21161 resultColumn.bindStarLinkColumn( 21162 tableModel.getColumns().get(z).getColumnObject()); 21163 } 21164 } 21165 } else if (modelManager.getModel(tableElement) instanceof QueryTable) { 21166 QueryTable tableModel = (QueryTable) modelManager 21167 .getModel(tableElement); 21168 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 21169 for (ResultColumn item : tableModel.getColumns()) { 21170 if (item.hasStarLinkColumn()) { 21171 for (TObjectName starLinkColumn : item 21172 .getStarLinkColumnList()) { 21173 resultColumn.bindStarLinkColumn(starLinkColumn); 21174 } 21175 } else if (item.getColumnObject() instanceof TObjectName) { 21176 resultColumn.bindStarLinkColumn( 21177 (TObjectName) item.getColumnObject()); 21178 } 21179 } 21180 } 21181 } 21182 continue; 21183 } 21184 resultColumn.bindStarLinkColumn(columnName); 21185 } 21186 } 21187 } 21188 } 21189 } 21190 } 21191 21192 resultSet.setDetermined(isDetermined); 21193 } 21194 } 21195 } 21196 21197 private void analyzeResultColumn(TResultColumn column, EffectType effectType) { 21198 // A SELECT * star column whose source resolves to a determined result set 21199 // is bound to a LinkedHashMap of per-column ResultColumns (see 21200 // ModelFactory.createStarResultColumn), and its data-flow relationships 21201 // are already created inline during star expansion in analyzeSelectStmt(). 21202 // Re-analyzing the raw "*" here is redundant; skip it. (analyzeDataFlowRelation 21203 // keeps the same guard as a defensive backstop.) 21204 if (modelManager.getModel(column) instanceof LinkedHashMap) { 21205 return; 21206 } 21207 TExpression expression = column.getExpr(); 21208 if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 21209 expression = expression.getRightOperand(); 21210 } 21211 21212 if (expression.getExpressionType() == EExpressionType.array_t) { 21213 if (expression.getExprList() != null) { 21214 for (TExpression expr : expression.getExprList()) { 21215 columnsInExpr visitor = new columnsInExpr(); 21216 expr.inOrderTraverse(visitor); 21217 List<TObjectName> objectNames = visitor.getObjectNames(); 21218 21219 List<TParseTreeNode> functions = visitor.getFunctions(); 21220 21221 if (functions != null && !functions.isEmpty()) { 21222 analyzeFunctionDataFlowRelation(column, functions, effectType); 21223 } 21224 21225 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 21226 if (subquerys != null && !subquerys.isEmpty()) { 21227 analyzeSubqueryDataFlowRelation(column, subquerys, effectType); 21228 } 21229 21230 analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions); 21231 21232 List<TParseTreeNode> constants = visitor.getConstants(); 21233 Object columnObject = modelManager.getModel(column); 21234 analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions); 21235 21236 analyzeRecordSetRelation(functions, effectType); 21237 // analyzeResultColumnImpact( column, effectType, functions); 21238 } 21239 } 21240 else { 21241 List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>(); 21242 TConstant constant = new TConstant(); 21243 constant.setString(expression.toString()); 21244 constants.add(constant); 21245 Object columnObject = modelManager.getModel(column); 21246 analyzeConstantDataFlowRelation(columnObject, constants, effectType, null); 21247 } 21248 } else { 21249 columnsInExpr visitor = new columnsInExpr(); 21250 expression.inOrderTraverse(visitor); 21251 List<TObjectName> objectNames = visitor.getObjectNames(); 21252 21253 List<TParseTreeNode> functions = visitor.getFunctions(); 21254 21255 if (functions != null && !functions.isEmpty()) { 21256 analyzeFunctionDataFlowRelation(column, functions, effectType); 21257 } 21258 21259 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 21260 if (subquerys != null && !subquerys.isEmpty()) { 21261 analyzeSubqueryDataFlowRelation(column, subquerys, effectType); 21262 } 21263 21264 analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions); 21265 21266 List<TParseTreeNode> constants = visitor.getConstants(); 21267 Object columnObject = modelManager.getModel(column); 21268 analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions); 21269 21270 analyzeRecordSetRelation(functions, effectType); 21271 // analyzeResultColumnImpact( column, effectType, functions); 21272 } 21273 } 21274 21275 21276 private void analyzeValueColumn(Object object, TResultColumn column, EffectType effectType) { 21277 TExpression expression = column.getExpr(); 21278 if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 21279 expression = expression.getRightOperand(); 21280 } 21281 21282 if (expression.getExpressionType() == EExpressionType.array_t) { 21283 if (expression.getExprList() != null) { 21284 for (TExpression expr : expression.getExprList()) { 21285 columnsInExpr visitor = new columnsInExpr(); 21286 expr.inOrderTraverse(visitor); 21287 List<TObjectName> objectNames = visitor.getObjectNames(); 21288 analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null); 21289 List<TParseTreeNode> constants = visitor.getConstants(); 21290 analyzeConstantDataFlowRelation(object, constants, effectType, null); 21291 } 21292 } 21293 else { 21294 List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>(); 21295 TConstant constant = new TConstant(); 21296 constant.setString(expression.toString()); 21297 constants.add(constant); 21298 Object columnObject = modelManager.getModel(column); 21299 analyzeConstantDataFlowRelation(object, constants, effectType, null); 21300 } 21301 } else { 21302 columnsInExpr visitor = new columnsInExpr(); 21303 expression.inOrderTraverse(visitor); 21304 List<TObjectName> objectNames = visitor.getObjectNames(); 21305 analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null); 21306 List<TParseTreeNode> constants = visitor.getConstants(); 21307 analyzeConstantDataFlowRelation(object, constants, effectType, null); } 21308 } 21309 21310 private void analyzeTableColumn(TableColumn tableColumn, TFunctionCall functionCall, EffectType effectType) { 21311 List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>(); 21312 functions.add(functionCall); 21313 21314 if (functions != null && !functions.isEmpty()) { 21315 analyzeFunctionDataFlowRelation(tableColumn, functions, effectType); 21316 } 21317 21318 analyzeRecordSetRelation(functions, effectType); 21319 } 21320 21321 private void analyzeRecordSetRelation(List<TParseTreeNode> functions, EffectType effectType) { 21322 if (functions == null || functions.size() == 0) 21323 return; 21324 21325 List<TFunctionCall> aggregateFunctions = new ArrayList<TFunctionCall>(); 21326 for (TParseTreeNode function : functions) { 21327 if (function instanceof TFunctionCall && isAggregateFunction((TFunctionCall) function)) { 21328 aggregateFunctions.add((TFunctionCall) function); 21329 } 21330 } 21331 21332 if (aggregateFunctions.size() == 0) 21333 return; 21334 21335 for (int i = 0; i < aggregateFunctions.size(); i++) { 21336 TFunctionCall function = aggregateFunctions.get(i); 21337 21338 TCustomSqlStatement stmt = stmtStack.peek(); 21339 if (stmt instanceof TSelectSqlStatement) { 21340 TSelectSqlStatement select = (TSelectSqlStatement) stmt; 21341 if (select.getGroupByClause() != null) { 21342 if (select.getGroupByClause().isAllModifier()) { 21343 // GROUP BY ALL: implicit grouping columns are the 21344 // non-aggregate expressions in the SELECT list. 21345 TResultColumnList resultColumns = select.getResultColumnList(); 21346 if (resultColumns != null) { 21347 for (int j = 0; j < resultColumns.size(); j++) { 21348 TResultColumn column = resultColumns.getResultColumn(j); 21349 TExpression expr = column.getExpr(); 21350 if (expr == null) 21351 continue; 21352 columnsInExpr aggVisitor = new columnsInExpr(); 21353 expr.inOrderTraverse(aggVisitor); 21354 boolean containsAggregate = false; 21355 for (TParseTreeNode funcNode : aggVisitor.getFunctions()) { 21356 if (funcNode instanceof TFunctionCall 21357 && isAggregateFunction((TFunctionCall) funcNode)) { 21358 containsAggregate = true; 21359 break; 21360 } 21361 } 21362 if (!containsAggregate) { 21363 analyzeAggregate(function, expr); 21364 } 21365 } 21366 } 21367 } else { 21368 TGroupByItemList groupByList = select.getGroupByClause().getItems(); 21369 for (int j = 0; j < groupByList.size(); j++) { 21370 TGroupByItem groupBy = groupByList.getGroupByItem(j); 21371 TExpression expr = groupBy.getExpr(); 21372 analyzeAggregate(function, expr); 21373 } 21374 } 21375 21376 if (select.getGroupByClause().getHavingClause() != null) { 21377 analyzeAggregate(function, select.getGroupByClause().getHavingClause()); 21378 } 21379 // if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) 21380 { 21381 analyzeAggregate(function, null); 21382 } 21383 } else { 21384 analyzeAggregate(function, null); 21385 } 21386 } 21387 } 21388 } 21389 21390 private void analyzeDataFlowRelation(TParseTreeNode gspObject, List<TObjectName> objectNames, 21391 TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions) { 21392 Object columnObject = modelManager.getModel(gspObject); 21393 analyzeDataFlowRelation(columnObject, objectNames, exceptColumnList, effectType, functions, null); 21394 } 21395 21396 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType, 21397 List<TParseTreeNode> functions) { 21398 return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, null); 21399 } 21400 21401 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType, 21402 List<TParseTreeNode> functions, Process process) { 21403 return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, process); 21404 } 21405 21406 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, 21407 TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process) { 21408 return analyzeDataFlowRelation(modelObject, objectNames, exceptColumnList, effectType, functions, process, null); 21409 } 21410 21411 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, 21412 TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process, Integer valueIndex) { 21413 if (objectNames == null || objectNames.size() == 0) 21414 return null; 21415 21416 // Reject model objects this method cannot turn into a relationship BEFORE 21417 // creating one, since createDataFlowRelation() registers the relation 21418 // globally and an early return afterwards would leak an empty relation. 21419 // 21420 // - LinkedHashMap: a SELECT * star column whose source resolves to a 21421 // determined result set is expanded into per-column ResultColumns held 21422 // in a LinkedHashMap by ModelFactory.createStarResultColumn(), with its 21423 // data-flow relationships created inline during star expansion in 21424 // analyzeSelectStmt(). Re-analyzing the raw "*" here is a no-op. 21425 // - null: modelManager.getModel() found no binding for the gsp object. 21426 if (modelObject == null || modelObject instanceof LinkedHashMap) { 21427 return null; 21428 } 21429 // Lineage is best-effort: an unexpected model type should not abort the 21430 // whole statement's lineage (this used to throw UnsupportedOperationException). 21431 // Log it for diagnosis and skip just this column instead. 21432 if (!(modelObject instanceof ResultColumn) && !(modelObject instanceof TableColumn)) { 21433 logger.warn("analyzeDataFlowRelation: unhandled model type " 21434 + modelObject.getClass().getName() + ", effectType=" + effectType); 21435 return null; 21436 } 21437 21438 boolean isStar = false; 21439 boolean showStar = false; 21440 21441 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 21442 relation.setEffectType(effectType); 21443 relation.setProcess(process); 21444 21445 if (functions != null && !functions.isEmpty()) { 21446 relation.setFunction(getFunctionName(functions.get(0))); 21447 } 21448 21449 int columnIndex = -1; 21450 21451 boolean isOut = false; 21452 21453 if (modelObject instanceof ResultColumn) { 21454 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 21455 21456 if ("*".equals(((ResultColumn) modelObject).getName())) { 21457 isStar = true; 21458 showStar = ((ResultColumn) modelObject).isShowStar(); 21459 } 21460 21461 if (((ResultColumn) modelObject).getResultSet() != null) { 21462 columnIndex = ((ResultColumn) modelObject).getResultSet().getColumns().indexOf(modelObject); 21463 } 21464 } else if (modelObject instanceof TableColumn) { 21465 Table table = ((TableColumn) modelObject).getTable(); 21466 if(table.getSubType() == SubType.out && isNotInProcedure(table)){ 21467 isOut = true; 21468 relation.addSource(new TableColumnRelationshipElement((TableColumn) modelObject)); 21469 } 21470 else { 21471 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 21472 } 21473 21474 if ("*".equals(((TableColumn) modelObject).getName())) { 21475 isStar = true; 21476 } 21477 21478 if (((TableColumn) modelObject).getTable() != null) { 21479 columnIndex = ((TableColumn) modelObject).getTable().getColumns().indexOf(modelObject); 21480 } 21481 } 21482 // No trailing else: modelObject is guaranteed to be a ResultColumn or 21483 // TableColumn here (validated and logged above before relation creation). 21484 21485 for (int i = 0; i < objectNames.size(); i++) { 21486 TObjectName columnName = objectNames.get(i); 21487 if (columnName.toString().indexOf(".") == -1 && isConstant(columnName)) { 21488 boolean isConstant = true; 21489 if (columnName.getSourceTable() != null) { 21490 Table tableModel = modelManager.getTableByName( 21491 DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString())); 21492 if (tableModel != null && tableModel.getColumns() != null) { 21493 for (int j = 0; j < tableModel.getColumns().size(); j++) { 21494 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 21495 getColumnName(tableModel.getColumns().get(j).getName()))) { 21496 isConstant = false; 21497 break; 21498 } 21499 } 21500 } 21501 } 21502 21503 if (isConstant) { 21504 if (option.isShowConstantTable()) { 21505 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 21506 TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false); 21507 if(tableColumn!=null) { 21508 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 21509 } 21510 } 21511 continue; 21512 } 21513 } 21514 if (columnName.getDbObjectType() == EDbObjectType.variable) { 21515 boolean find = false; 21516 List<String> segments = SQLUtil.parseNames(columnName.toString()); 21517 if (segments.size() == 1) { 21518 Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString())); 21519 if (variable != null) { 21520 TableColumn columnModel = variable.getColumns().get(0); 21521 if(variable.getColumns().size()>0){ 21522 TableColumn matchColumn = matchColumn(variable.getColumns(), columnName); 21523 if(matchColumn!=null){ 21524 columnModel = matchColumn; 21525 } 21526 } 21527 if(isOut){ 21528 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 21529 } 21530 else { 21531 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21532 } 21533 find = true; 21534 } else { 21535 if (columnName.toString().matches("\\$\\d+")) { 21536 TCustomSqlStatement stmt = stmtStack.peek(); 21537 Procedure procedure = modelManager 21538 .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt))); 21539 if(procedure!=null) { 21540 Variable cursorVariable = modelFactory.createVariable(procedure.getArguments().get(Integer.valueOf(columnName.toString().replace("$", "")) - 1).getName()); 21541 if (isOut) { 21542 relation.setTarget(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0))); 21543 } else { 21544 relation.addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0))); 21545 } 21546 } 21547 } else { 21548 Variable cursorVariable = modelFactory.createVariable(columnName); 21549 cursorVariable.setCreateTable(true); 21550 cursorVariable.setSubType(SubType.record); 21551 TableColumn variableProperty = null; 21552 if(cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) { 21553 variableProperty = modelFactory.createTableColumn(cursorVariable, columnName, 21554 true); 21555 } 21556 else{ 21557 variableProperty = cursorVariable.getColumns().get(0); 21558 } 21559 if (isOut) { 21560 relation.setTarget(new TableColumnRelationshipElement(variableProperty)); 21561 } else { 21562 relation.addSource(new TableColumnRelationshipElement(variableProperty)); 21563 } 21564 } 21565 find = true; 21566 } 21567 } else if (option.getVendor() == EDbVendor.dbvoracle && columnName.getTableToken()!=null) { 21568 Variable cursorVariable = modelFactory 21569 .createVariable(columnName.getTableToken().toString()); 21570 21571 TObjectName variableColumnName = new TObjectName(); 21572 variableColumnName.setString(segments.get(segments.size() - 1)); 21573 21574 if (cursorVariable.getColumns() != null) { 21575 for (int j = 0; j < cursorVariable.getColumns().size(); j++) { 21576 if (getColumnName(variableColumnName) 21577 .equals(getColumnName(cursorVariable.getColumns().get(j).getColumnObject()))) { 21578 TableColumn columnModel = cursorVariable.getColumns().get(j); 21579 if (isOut) { 21580 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 21581 } else { 21582 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21583 } 21584 find = true; 21585 } 21586 } 21587 } 21588 21589 if (!find) { 21590 TableColumn variableColumn = new TableColumn(cursorVariable, variableColumnName); 21591 cursorVariable.addColumn(variableColumn); 21592 if (isOut) { 21593 relation.setTarget(new TableColumnRelationshipElement(variableColumn)); 21594 } else { 21595 relation.addSource(new TableColumnRelationshipElement(variableColumn)); 21596 } 21597 } 21598 } else { 21599 Table variable = modelManager 21600 .getTableByName(DlineageUtil.getTableFullName(segments.get(segments.size() - 2))); 21601 if (variable != null) { 21602 for (int j = 0; j < variable.getColumns().size(); j++) { 21603 if (getColumnName(columnName) 21604 .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) { 21605 TableColumn columnModel = variable.getColumns().get(j); 21606 if (isOut) { 21607 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 21608 } else { 21609 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21610 } 21611 find = true; 21612 } 21613 } 21614 } 21615 } 21616 if (!find) { 21617 TCustomSqlStatement stmt = stmtStack.peek(); 21618 if (getProcedureParentName(stmt) != null) { 21619 Procedure procedure = modelManager 21620 .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt))); 21621 if (procedure != null && procedure.getArguments() != null) { 21622 for (Argument argument : procedure.getArguments()) { 21623 if (DlineageUtil.getTableFullName(argument.getName()) 21624 .equals(DlineageUtil.getTableFullName(columnName.toString()))) { 21625 relation.addSource(new ArgumentRelationshipElement(argument)); 21626 } 21627 } 21628 } 21629 } 21630 } 21631 continue; 21632 } 21633 21634 // Handle sequence pseudocolumn syntax (sequence.NEXTVAL or sequence.CURRVAL) 21635 // Used by Oracle, Snowflake, and accepted by other vendors for compatibility 21636 if(("NEXTVAL".equalsIgnoreCase(columnName.getColumnNameOnly()) || "CURRVAL".equalsIgnoreCase(columnName.getColumnNameOnly()))){ 21637 List<String> segments = SQLUtil.parseNames(columnName.toString()); 21638 if (segments.size() > 1) { 21639 segments.remove(segments.size()-1); 21640 Table table = modelFactory.createTableByName(SQLUtil.mergeSegments(segments, 0), true); 21641 table.setSequence(true); 21642 TableColumn seqCursor = modelFactory.createTableColumn(table, columnName, true); 21643 relation.addSource(new TableColumnRelationshipElement(seqCursor)); 21644 continue; 21645 } 21646 } 21647 21648 { 21649 if (columnName.getSourceTable() != null) { 21650 21651 } 21652 else { 21653 Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString())); 21654 if (variable == null) { 21655 variable = modelManager 21656 .getTableByName(DlineageUtil.getTableFullName(columnName.getTableString())); 21657 if (variable != null && variable.isCursor()) { 21658 TableColumn variableColumn = modelFactory.createInsertTableColumn(variable, columnName); 21659 if (variableColumn != null) { 21660 if(isOut){ 21661 relation.setTarget(new TableColumnRelationshipElement(variableColumn)); 21662 } 21663 else { 21664 relation.addSource(new TableColumnRelationshipElement(variableColumn)); 21665 } 21666 } else { 21667 if(isOut){ 21668 relation.setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0))); 21669 } 21670 else { 21671 relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0))); 21672 } 21673 } 21674 continue; 21675 } 21676 } else if (variable.isVariable() || variable.isCursor()) { 21677 TableColumn columnModel = variable.getColumns().get(0); 21678 if (valueIndex != null) { 21679 if(isOut){ 21680 relation.setTarget(new TableColumnRelationshipElement(columnModel, valueIndex)); 21681 } 21682 else { 21683 relation.addSource(new TableColumnRelationshipElement(columnModel, valueIndex)); 21684 } 21685 } else { 21686 if(isOut){ 21687 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 21688 } 21689 else { 21690 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21691 } 21692 } 21693 continue; 21694 } 21695 } 21696 } 21697 21698 if (columnName.getColumnNameOnly().startsWith("@") 21699 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 21700 continue; 21701 } 21702 21703 if (columnName.getColumnNameOnly().startsWith(":") 21704 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 21705 Table variable = modelManager 21706 .getTableByName(DlineageUtil.getTableFullName(columnName.getColumnNameOnly().replace(":", ""))); 21707 if (variable != null) { 21708 for (int j = 0; j < variable.getColumns().size(); j++) { 21709 if (getColumnName(columnName).replace(":", "") 21710 .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) { 21711 TableColumn columnModel = variable.getColumns().get(j); 21712 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21713 } 21714 } 21715 } 21716 continue; 21717 } 21718 21719 boolean linkedFirstTable = false; 21720 21721 TCustomSqlStatement stmt = stmtStack.peek(); 21722 TTableList tableList = stmt.tables; 21723 if ((tableList == null || tableList.size() == 0) && (hiveFromTables != null && hiveFromTables.size() > 0)) { 21724 tableList = hiveFromTables; 21725 } 21726 21727 List<TTable> tables = new ArrayList<TTable>(); 21728 { 21729 TTable table = columnName.getSourceTable(); 21730 21731 // 针对CursorVariable特殊处理 21732 if (columnName.getTableToken() != null) { 21733 21734 Table tableModel = null; 21735 if (table != null && modelManager.getModel(table) instanceof Table) { 21736 tableModel = (Table) modelManager.getModel(table); 21737 } 21738 21739 if (tableModel == null) { 21740 tableModel = modelManager 21741 .getTableByName(DlineageUtil.getTableFullName(columnName.getTableToken().toString())); 21742 } 21743 21744 if (tableModel == null) { 21745 TCustomSqlStatement currentStmt = ModelBindingManager.getGlobalStmtStack().peek(); 21746 String procedureName = DlineageUtil.getProcedureParentName(currentStmt); 21747 String variableString = columnName.getTableToken().toString(); 21748 if (variableString.startsWith(":")) { 21749 variableString = variableString.substring(variableString.indexOf(":") + 1); 21750 } 21751 if (!SQLUtil.isEmpty(procedureName)) { 21752 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 21753 } 21754 21755 if (modelManager 21756 .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) { 21757 tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 21758 } 21759 } 21760 21761 if (tableModel != null) { 21762 21763 if (table == null) { 21764 table = tableModel.getTableObject(); 21765 } 21766 21767 if (tableModel.isVariable()) { 21768 if (!isStar && "*".equals(getColumnName(columnName))) { 21769 TObjectName[] columns = modelManager.getTableColumns(table); 21770 for (int j = 0; j < columns.length; j++) { 21771 TObjectName objectName = columns[j]; 21772 if (objectName == null || "*".equals(getColumnName(objectName))) { 21773 continue; 21774 } 21775 TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName, 21776 false); 21777 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21778 } 21779 } else { 21780 if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) { 21781 21782 for (int j = 0; j < tableModel.getColumns().size(); j++) { 21783 TableColumn columnModel = tableModel.getColumns().get(j); 21784 if (exceptColumnList != null) { 21785 boolean flag = false; 21786 for (TObjectName objectName : exceptColumnList) { 21787 if (getColumnName(objectName) 21788 .equals(getColumnName(columnModel.getColumnObject()))) { 21789 flag = true; 21790 break; 21791 } 21792 } 21793 if (flag) { 21794 continue; 21795 } 21796 } 21797 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21798 } 21799 21800 if (isStar && showStar) { 21801 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 21802 false); 21803 if (columnModel == null) { 21804 if (tableModel.isCreateTable()) { 21805 for (TableColumn tableColumn : tableModel.getColumns()) { 21806 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 21807 relation.setShowStarRelation(true); 21808 } 21809 } 21810 } else { 21811 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21812 relation.setShowStarRelation(true); 21813 } 21814 } 21815 } else { 21816 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 21817 false); 21818 21819 if(columnModel == null && containStarColumn(tableModel.getColumns())){ 21820 columnModel = getStarColumn(tableModel.getColumns()); 21821 if (columnModel != null && tableModel.getSubType() == SubType.record_type) { 21822 if(!"*".equals(getColumnName(columnName))){ 21823 columnModel.bindStarLinkColumn(columnName); 21824 } 21825 } 21826 } 21827 21828 if (columnModel == null) { 21829 continue; 21830 } 21831 if (columnModel.hasStarLinkColumn()) { 21832 relation.addSource(new TableColumnRelationshipElement(columnModel, 21833 columnModel.getStarLinkColumnNames() 21834 .indexOf(DlineageUtil.getColumnName(columnName)))); 21835 } else { 21836 if (isOut) { 21837 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 21838 } else { 21839 relation.addSource(new TableColumnRelationshipElement(columnModel)); 21840 } 21841 } 21842 if (columnName.getSourceTable() != null 21843 && columnName.getSourceTable().getTableType() == ETableSource.function) { 21844 analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(), 21845 effectType); 21846 } 21847 } 21848 } 21849 continue; 21850 } 21851 } 21852 } 21853 21854 if (table == null) { 21855 table = modelManager.getTable(stmt, columnName); 21856 } 21857 21858 if (table == null) { 21859 if (columnName.getTableToken() != null || !"*".equals(getColumnName(columnName))) { 21860 table = columnName.getSourceTable(); 21861 } 21862 21863 if (table == null && !SQLUtil.isEmpty(columnName.getTableString())) { 21864 table = modelManager.getTableFromColumn(columnName); 21865 } 21866 } 21867 21868 if (table == null) { 21869 if (tableList != null) { 21870 for (int j = 0; j < tableList.size(); j++) { 21871 if (table != null) 21872 break; 21873 21874 TTable tTable = tableList.getTable(j); 21875 if (tTable.getTableType().name().startsWith("open")) { 21876 continue; 21877 } 21878 21879 if (getTableLinkedColumns(tTable) != null && getTableLinkedColumns(tTable).size() > 0) { 21880 for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) { 21881 TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z); 21882 if ("*".equals(getColumnName(refer))) 21883 continue; 21884 // For BigQuery struct field access, match base column name from FieldPath 21885 String structFullName = getStructFieldFullName(columnName); 21886 if (structFullName != null) { 21887 String baseName = getStructFieldBaseName(columnName); 21888 if (baseName != null && DlineageUtil.getIdentifierNormalColumnName(getColumnName(refer)) 21889 .equals(DlineageUtil.getIdentifierNormalColumnName(baseName))) { 21890 table = tTable; 21891 break; 21892 } 21893 } 21894 if (getColumnName(refer).equals(getColumnName(columnName))) { 21895 table = tTable; 21896 break; 21897 } 21898 } 21899 } 21900 21901 if (tTable.getLinkTable() != null) { 21902 tTable = tTable.getLinkTable(); 21903 for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) { 21904 TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z); 21905 if ("*".equals(getColumnName(refer))) 21906 continue; 21907 if (getColumnName(refer).equals(getColumnName(columnName))) { 21908 table = tTable; 21909 break; 21910 } 21911 } 21912 } 21913 21914 if (table != null) 21915 break; 21916 21917 if (columnName.getTableToken() != null && (columnName.getTableToken().getAstext() 21918 .equalsIgnoreCase(tTable.getName()) 21919 || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) { 21920 table = tTable; 21921 break; 21922 } 21923 } 21924 } 21925 21926 if (table == null) { 21927 for (int j = 0; j < tableList.size(); j++) { 21928 if (table != null) 21929 break; 21930 21931 TTable tTable = tableList.getTable(j); 21932 Object model = ModelBindingManager.get().getModel(tTable); 21933 if (model instanceof Table) { 21934 Table tableModel = (Table) model; 21935 for (int z = 0; tableModel.getColumns() != null 21936 && z < tableModel.getColumns().size(); z++) { 21937 TableColumn refer = tableModel.getColumns().get(z); 21938 if (getColumnName(refer.getName()).equals(getColumnName(columnName))) { 21939 table = tTable; 21940 break; 21941 } 21942 if (refer.hasStarLinkColumn()) { 21943 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 21944 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 21945 table = tTable; 21946 break; 21947 } 21948 } 21949 } 21950 } 21951 } else if (model instanceof QueryTable) { 21952 QueryTable tableModel = (QueryTable) model; 21953 for (int z = 0; tableModel.getColumns() != null 21954 && z < tableModel.getColumns().size(); z++) { 21955 ResultColumn refer = tableModel.getColumns().get(z); 21956 // Try FieldPath-based matching first 21957 String structFullName = getStructFieldFullName(columnName); 21958 if (structFullName != null) { 21959 String baseName = getStructFieldBaseName(columnName); 21960 if (baseName != null && DlineageUtil.getIdentifierNormalColumnName(refer.getName()) 21961 .equals(DlineageUtil.getIdentifierNormalColumnName(baseName))) { 21962 table = tTable; 21963 break; 21964 } 21965 } 21966 List<String> splits = SQLUtil.parseNames(columnName.toString()); 21967 if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 21968 if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()) 21969 .equals(DlineageUtil 21970 .getIdentifierNormalColumnName(getColumnName(splits.get(0))))) { 21971 table = tTable; 21972 break; 21973 } 21974 } 21975 else if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals( 21976 DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) { 21977 table = tTable; 21978 break; 21979 } 21980 if (refer.hasStarLinkColumn()) { 21981 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 21982 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 21983 table = tTable; 21984 break; 21985 } 21986 } 21987 } 21988 } 21989 } 21990 } 21991 } 21992 } 21993 21994 if (columnName.getTableToken() == null && "*".equals(getColumnName(columnName))) { 21995 if (!hasJoin(stmt)) { 21996 tables.add(table); 21997 } else { 21998 for (int j = 0; j < tableList.size(); j++) { 21999 tables.add(tableList.getTable(j)); 22000 } 22001 } 22002 } else if (table != null) { 22003 tables.add(table); 22004 } 22005 22006 // 此处特殊处理,多表关联无法找到 column 所属的 Table, tTable.getLinkedColumns 22007 // 也找不到,退而求其次采用第一个表 22008 22009 if (stmt.getParentStmt() != null && isApplyJoin(stmt.getParentStmt()) 22010 && (tableList != null && tableList.size() > 0)) { 22011 stmt = stmt.getParentStmt(); 22012 TTable applyTable = tableList.getTable(0); 22013 if (modelManager.getModel(table) == null) { 22014 modelFactory.createTable(applyTable); 22015 } 22016 } 22017 22018 if (columnName.toString().indexOf(".")==-1 && isConstant(columnName)) { 22019 boolean isConstant = true; 22020 if (columnName.getSourceTable() != null) { 22021 Table tableModel = modelManager.getTableByName( 22022 DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString())); 22023 if (tableModel != null && tableModel.getColumns() != null) { 22024 for (int j = 0; j < tableModel.getColumns().size(); j++) { 22025 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 22026 getColumnName(tableModel.getColumns().get(j).getName()))) { 22027 isConstant = false; 22028 break; 22029 } 22030 } 22031 } 22032 } 22033 22034 if (isConstant) { 22035 if (option.isShowConstantTable()) { 22036 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 22037 TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false); 22038 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 22039 } 22040 continue; 22041 } 22042 } 22043 22044 if (tableList != null && tableList.size() != 0 && tables.size() == 0 22045 && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) { 22046 if (modelManager.getModel(stmt) instanceof ResultSet) { 22047 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt); 22048 boolean find = false; 22049 for (ResultColumn resultColumn : resultSetModel.getColumns()) { 22050 if(resultColumn.equals(modelObject)) { 22051 continue; 22052 } 22053 if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) { 22054 if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) { 22055 if (resultColumn.getColumnObject() != null) { 22056 int startToken = resultColumn.getColumnObject().getStartToken().posinlist; 22057 int endToken = resultColumn.getColumnObject().getEndToken().posinlist; 22058 if (columnName.getStartToken().posinlist >= startToken 22059 && columnName.getEndToken().posinlist <= endToken) { 22060 continue; 22061 } 22062 } 22063 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 22064 find = true; 22065 break; 22066 } 22067 } 22068 } 22069 if (find) { 22070 continue; 22071 } 22072 } 22073 22074 // Structured-dataflow outer field resolution: an unresolved 22075 // reference like nodes1.key (or t.nodes1.key) may be a 22076 // struct-field projection produced by a structured generator 22077 // (e.g. Spark explode(from_json(...))) in a visible subquery. 22078 // Link directly to the matching FunctionResultColumn so the 22079 // exact source path (nodes[*].key) flows through. 22080 if (tryAppendStructuredFieldRelation(relation, columnName, tableList)) { 22081 continue; 22082 } 22083 22084 TObjectName pseudoTableName = new TObjectName(); 22085 // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl) 22086 // Otherwise fall back to default pseudo table name 22087 String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName); 22088 pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column"); 22089 Table pseudoTable = modelFactory.createTableByName(pseudoTableName); 22090 pseudoTable.setPseudo(true); 22091 TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true); 22092 22093 // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col), 22094 // add the pseudo table column as source 22095 if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) { 22096 if (isOut) { 22097 relation.setTarget(new TableColumnRelationshipElement(pseudoTableColumn)); 22098 } else { 22099 relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn)); 22100 } 22101 } 22102 22103 if (isLinkOrphanColumnToFirstTable()) { 22104 TTable orphanTable = tableList.getTable(0); 22105 tables.add(orphanTable); 22106 Object tableModel = modelManager.getModel(orphanTable); 22107 if (tableModel == null) { 22108 if(orphanTable.getSubquery()!=null) { 22109 QueryTable queryTable = modelFactory.createQueryTable(orphanTable); 22110 TSelectSqlStatement subquery = orphanTable.getSubquery(); 22111 analyzeSelectStmt(subquery); 22112 } 22113 else { 22114 tableModel = modelFactory.createTable(orphanTable); 22115 } 22116 } 22117 if (tableModel instanceof Table) { 22118 TableColumn orphanColum = modelFactory.createTableColumn((Table) tableModel, columnName, false); 22119 if(orphanColum!=null) { 22120 ErrorInfo errorInfo = new ErrorInfo(); 22121 errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN); 22122 errorInfo.setErrorMessage("Link orphan column [" + columnName.toString() 22123 + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]"); 22124 errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo, 22125 columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 22126 errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo, 22127 columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(), 22128 ModelBindingManager.getGlobalHash())); 22129 errorInfo.fillInfo(this); 22130 errorInfos.add(errorInfo); 22131 } 22132 if (orphanTable.getSubquery() != null) { 22133 TSelectSqlStatement subquery = orphanTable.getSubquery(); 22134 if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) { 22135 TTable subqueryTable = subquery.getTables().getTable(0); 22136 Object sourceTable = modelManager.getModel(subqueryTable); 22137 if(sourceTable instanceof Table) { 22138 modelFactory.createTableColumn((Table) sourceTable, columnName, false); 22139 } 22140 else if(sourceTable instanceof ResultSet) { 22141 modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false); 22142 } 22143 } 22144 } 22145 else if (orphanTable.getCTE()!=null && orphanTable.getCTE().getSubquery() != null) { 22146 TSelectSqlStatement subquery = orphanTable.getCTE().getSubquery(); 22147 if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) { 22148 TTable subqueryTable = subquery.getTables().getTable(0); 22149 Object sourceTable = modelManager.getModel(subqueryTable); 22150 if(sourceTable instanceof Table) { 22151 modelFactory.createTableColumn((Table) sourceTable, columnName, false); 22152 } 22153 else if(sourceTable instanceof ResultSet) { 22154 modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false); 22155 } 22156 } 22157 } 22158 } 22159 22160 linkedFirstTable = true; 22161 } 22162 } 22163 } 22164 22165 for (int k = 0; k < tables.size(); k++) { 22166 TTable table = tables.get(k); 22167 if (table != null) { 22168 Object object = modelManager.getModel(table); 22169 if(object instanceof PivotedTable) { 22170 TPivotClause clause = (TPivotClause)((PivotedTable)object).getGspObject(); 22171 if(clause.getAliasClause()!=null) { 22172 object = modelManager.getModel(clause.getAliasClause()); 22173 } 22174 } 22175 if (object == null && table.getTableType() == ETableSource.objectname) { 22176 if (table.getCTE() != null) { 22177 QueryTable queryTable = modelFactory.createQueryTable(table); 22178 TSelectSqlStatement subquery = table.getCTE().getSubquery(); 22179 analyzeSelectStmt(subquery); 22180 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 22181 22182 if (resultSetModel != null && resultSetModel != queryTable 22183 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 22184 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 22185 impactRelation.setEffectType(EffectType.select); 22186 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 22187 resultSetModel.getRelationRows())); 22188 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 22189 queryTable.getRelationRows())); 22190 } 22191 22192 if (resultSetModel != null && resultSetModel != queryTable) { 22193 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 22194 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 22195 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 22196 sourceColumn); 22197 22198 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 22199 queryRalation.setEffectType(EffectType.select); 22200 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 22201 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 22202 } 22203 } 22204 22205 object = queryTable; 22206 22207 } else { 22208 object = modelFactory.createTable(table); 22209 } 22210 } 22211 if (object instanceof Function) { 22212 relation.addSource(new ResultColumnRelationshipElement(((Function)object).getColumns().get(0))); 22213 continue; 22214 } else if (object instanceof ResultSet && !(object instanceof QueryTable)) { 22215 //Object tableModel = modelManager.getModel(columnName.getSourceTable()); 22216 appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName, 22217 (ResultSet)object); 22218 if(table.getTableType() == ETableSource.function && !relation.getSources().isEmpty()) { 22219 relation.getSources().stream().reduce((first, second) -> second).get().addTransform(Transform.FUNCTION, table); 22220 } 22221 continue; 22222 } 22223 else if (object instanceof Table) { 22224 Table tableModel = (Table) modelManager.getModel(table); 22225 if (tableModel != null) { 22226 if (!isStar && "*".equals(getColumnName(columnName))) { 22227 TObjectName[] columns = modelManager.getTableColumns(table); 22228 for (int j = 0; j < columns.length; j++) { 22229 TObjectName objectName = columns[j]; 22230 if (objectName == null || ("*".equals(getColumnName(objectName)) && tableModel.isDetermined())) { 22231 continue; 22232 } 22233 TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName, 22234 false); 22235 if(columnModel == null) { 22236 continue; 22237 } 22238 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22239 } 22240 } else { 22241 if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) { 22242 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 22243 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 22244 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 22245 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 22246 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 22247 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 22248 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 22249 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 22250 } 22251 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22252 if(tableModel.isDetermined()) { 22253 resultSet.getColumns().clear(); 22254 } 22255 } 22256 } 22257 22258 for (int j = 0; j < tableModel.getColumns().size(); j++) { 22259 TableColumn columnModel = tableModel.getColumns().get(j); 22260 if (exceptColumnList != null) { 22261 boolean flag = false; 22262 for (TObjectName objectName : exceptColumnList) { 22263 if (getColumnName(objectName) 22264 .equals(getColumnName(columnModel.getColumnObject()))) { 22265 flag = true; 22266 break; 22267 } 22268 } 22269 if (flag) { 22270 continue; 22271 } 22272 } 22273 22274 if (replaceAsIdentifierMap.containsKey(tableModel.getColumns().get(j).getName())) { 22275 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableModel.getColumns().get(j).getName()); 22276 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22277 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(tableModel.getColumns().get(j).getName())); 22278 Transform transform = new Transform(); 22279 transform.setType(Transform.EXPRESSION); 22280 TObjectName expression = new TObjectName(); 22281 expression.setString(expr.first); 22282 transform.setCode(expression); 22283 resultColumn.setTransform(transform); 22284 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 22285 } else { 22286 if(!replaceAsIdentifierMap.isEmpty()) { 22287 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 22288 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 22289 columnModel.getColumnObject()); 22290 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 22291 relation1.setEffectType(effectType); 22292 relation1.setProcess(process); 22293 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 22294 relation1.addSource(new TableColumnRelationshipElement(columnModel)); 22295 } 22296 else { 22297 relation.addSource( 22298 new TableColumnRelationshipElement(columnModel)); 22299 } 22300 } 22301 } 22302 22303 if (isStar && showStar) { 22304 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 22305 false); 22306 if (columnModel == null) { 22307 if(tableModel.isCreateTable()) { 22308 for (TableColumn tableColumn : tableModel.getColumns()) { 22309 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 22310 relation.setShowStarRelation(true); 22311 } 22312 } 22313 } else { 22314 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22315 relation.setShowStarRelation(true); 22316 } 22317 } 22318 } else { 22319 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 22320 false); 22321 if(columnModel == null) { 22322 if(tableModel.isCreateTable()) { 22323 boolean flag = false; 22324 // Try FieldPath-based matching first for BigQuery/Redshift struct fields 22325 String structFullName = getStructFieldFullName(columnName); 22326 if (structFullName != null && !flag) { 22327 for (TableColumn tableColumn : tableModel.getColumns()) { 22328 if (tableColumn.isStruct() 22329 && DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()) 22330 .equals(DlineageUtil.getIdentifierNormalColumnName(structFullName))) { 22331 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 22332 flag = true; 22333 if (modelObject instanceof ResultColumn) { 22334 ((ResultColumn) modelObject).setStruct(true); 22335 } else if (modelObject instanceof TableColumn) { 22336 ((TableColumn) modelObject).setStruct(true); 22337 } 22338 break; 22339 } 22340 } 22341 } 22342 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvbigquery || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvredshift) { 22343 for (TableColumn tableColumn : tableModel.getColumns()) { 22344 if(tableColumn.isStruct()) { 22345 List<String> names = SQLUtil.parseNames(tableColumn.getName()); 22346 if (modelObject instanceof TableColumn) { 22347 TableColumn targetColumn = (TableColumn) modelObject; 22348 if (targetColumn.isStruct()) { 22349 List<String> targetNames = SQLUtil 22350 .parseNames(targetColumn.getName()); 22351 if (!getColumnName(targetNames.get(0)) 22352 .equals(getColumnName(names.get(0)))) { 22353 continue; 22354 } 22355 } 22356 } 22357 else if (modelObject instanceof ResultColumn) { 22358 ResultColumn targetColumn = (ResultColumn) modelObject; 22359 if (targetColumn.isStruct()) { 22360 List<String> targetNames = SQLUtil 22361 .parseNames(targetColumn.getName()); 22362 if (!getColumnName(targetNames.get(0)) 22363 .equals(getColumnName(names.get(0)))) { 22364 continue; 22365 } 22366 } 22367 } 22368 for(String name: names) { 22369 if (getColumnName(name) 22370 .equals(getColumnName(modelObject.toString()))) { 22371 relation.addSource( 22372 new TableColumnRelationshipElement(tableColumn)); 22373 flag = true; 22374 if (modelObject instanceof ResultColumn) { 22375 ((ResultColumn)modelObject).setStruct(true); 22376 } 22377 else if (modelObject instanceof TableColumn) { 22378 ((TableColumn)modelObject).setStruct(true); 22379 } 22380 break; 22381 } 22382 } 22383 22384 if (!flag && tableModel.getColumns().size() == 1 && tableModel 22385 .getColumns().get(0).getSourceColumn() != null) { 22386 TableColumn sourceColumn = tableModel 22387 .getColumns().get(0).getSourceColumn(); 22388 Table sourceTable = sourceColumn.getTable(); 22389 TObjectName sourceColumnName = new TObjectName(); 22390 sourceColumnName.setString(sourceColumn.getName() + "." 22391 + columnName.getColumnNameOnly()); 22392 TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceColumnName, true); 22393 relation.addSource( 22394 new TableColumnRelationshipElement(sourceTableColumn)); 22395 flag = true; 22396 break; 22397 } 22398 } 22399 else if (getColumnName(tableColumn.getName()) 22400 .equals(getColumnName(modelObject.toString()))) { 22401 relation.addSource( 22402 new TableColumnRelationshipElement(tableColumn)); 22403 flag = true; 22404 break; 22405 } 22406 } 22407 if (modelObject instanceof TableColumn) { 22408 TableColumn column = (TableColumn) modelObject; 22409 for (TableColumn tableColumn : tableModel.getColumns()) { 22410 if (tableColumn.getColumnIndex() == null) { 22411 continue; 22412 } 22413 if (tableColumn.getName().toLowerCase() 22414 .indexOf(column.getName().toLowerCase()) == -1 22415 && tableColumn.getName().toLowerCase() 22416 .indexOf(column.getColumnObject().toString() 22417 .toLowerCase()) == -1) { 22418 continue; 22419 } 22420 flag = true; 22421 relation.addSource( 22422 new TableColumnRelationshipElement(tableColumn)); 22423 relation.setShowStarRelation(true); 22424 } 22425 if (flag) 22426 break; 22427 22428 } else if (modelObject instanceof ResultColumn) { 22429 ResultColumn column = (ResultColumn) modelObject; 22430 for (TableColumn tableColumn : tableModel.getColumns()) { 22431 if (tableColumn.getColumnIndex() == null) { 22432 continue; 22433 } 22434 if (tableColumn.getName().toLowerCase() 22435 .indexOf(column.getName().toLowerCase()) == -1 22436 && tableColumn.getName().toLowerCase() 22437 .indexOf(column.getColumnObject().toString() 22438 .toLowerCase()) == -1) { 22439 continue; 22440 } 22441 flag = true; 22442 relation.addSource( 22443 new TableColumnRelationshipElement(tableColumn)); 22444 relation.setShowStarRelation(true); 22445 } 22446 if (flag) 22447 break; 22448 22449 } 22450 } 22451 if (!flag 22452 && (isStar 22453 || getColumnName(columnName).equals(getColumnName(tableModel.getName())) 22454 || getColumnName(columnName).equals(getColumnName(tableModel.getAlias())))) { 22455 for (TableColumn tableColumn : tableModel.getColumns()) { 22456 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 22457 relation.setShowStarRelation(true); 22458 } 22459 } 22460 } 22461 } 22462 else { 22463 if (linkedFirstTable || columnModel.getCandidateParents() != null) { 22464 if (columnName.getCandidateTables() != null 22465 && columnName.getCandidateTables().size() > 1) { 22466 List<Object> candidateParents = new ArrayList<Object>(); 22467 for(TTable tableItem: columnName.getCandidateTables()) { 22468 Object model = modelManager.getModel(tableItem); 22469 if(model!=null) { 22470 candidateParents.add(model); 22471 } 22472 } 22473 if (candidateParents.size() > 1) { 22474 columnModel.setCandidateParents(candidateParents); 22475 } 22476 } 22477 } 22478 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22479 relation.setShowStarRelation(true); 22480 if(modelObject instanceof TableColumn) { 22481 TableColumn targetTableColumn = (TableColumn)modelObject; 22482 if(targetTableColumn.getTable().getSubType() == SubType.unnest && targetTableColumn.getTable().getColumns().size() == 1) { 22483 targetTableColumn.setSourceColumn(columnModel); 22484 targetTableColumn.setStruct(true); 22485 } 22486 } 22487 if (columnName.getSourceTable() != null 22488 && columnName.getSourceTable().getTableType() == ETableSource.function) { 22489 analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(), 22490 effectType); 22491 } 22492 } 22493 } 22494 } 22495 } 22496 } else if (modelManager.getModel(table) instanceof QueryTable) { 22497 QueryTable queryTable = (QueryTable) modelManager.getModel(table); 22498 22499 TObjectNameList cteColumns = null; 22500 TSelectSqlStatement subquery = null; 22501 if (queryTable.getTableObject().getCTE() != null) { 22502 subquery = queryTable.getTableObject().getCTE().getSubquery(); 22503 cteColumns = queryTable.getTableObject().getCTE().getColumnList(); 22504 } else if (queryTable.getTableObject().getAliasClause() != null 22505 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 22506 22507 } else if (queryTable.getTableObject().getTableExpr() != null 22508 && queryTable.getTableObject().getTableExpr().getSubQuery() != null) { 22509 subquery = queryTable.getTableObject().getTableExpr().getSubQuery(); 22510 } else { 22511 subquery = queryTable.getTableObject().getSubquery(); 22512 } 22513 22514 if (cteColumns != null) { 22515 for (int j = 0; j < cteColumns.size(); j++) { 22516 modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j)); 22517 } 22518 } 22519 22520 if (subquery != null && subquery.isCombinedQuery()) { 22521 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 22522 .getModel(subquery); 22523 22524 if (selectSetResultSetModel != null 22525 && !selectSetResultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 22526 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 22527 impactRelation.setEffectType(EffectType.select); 22528 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 22529 selectSetResultSetModel.getRelationRows())); 22530 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 22531 queryTable.getRelationRows())); 22532 } 22533 22534 if (selectSetResultSetModel != null) { 22535 if (getColumnName(columnName).equals("*")) { 22536 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 22537 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 22538 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 22539 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 22540 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 22541 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 22542 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 22543 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 22544 } 22545 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22546 if(selectSetResultSetModel.isDetermined()) { 22547 resultSet.getColumns().clear(); 22548 } 22549 } 22550 } 22551 22552 22553 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 22554 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 22555 if (cteColumns != null) { 22556 if (j < cteColumns.size()) { 22557 ResultColumn targetColumn = queryTable.getColumns().get(j); 22558 22559 if (exceptColumnList != null) { 22560 boolean flag = false; 22561 for (TObjectName objectName : exceptColumnList) { 22562 if (getColumnName(objectName) 22563 .equals(getColumnName(targetColumn.getName()))) { 22564 flag = true; 22565 break; 22566 } 22567 } 22568 if (flag) { 22569 continue; 22570 } 22571 } 22572 22573 if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) { 22574 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName()); 22575 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22576 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName())); 22577 Transform transform = new Transform(); 22578 transform.setType(Transform.EXPRESSION); 22579 TObjectName expression = new TObjectName(); 22580 expression.setString(expr.first); 22581 transform.setCode(expression); 22582 resultColumn.setTransform(transform); 22583 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 22584 } else { 22585 if(!replaceAsIdentifierMap.isEmpty()) { 22586 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 22587 TObjectName resultColumnName = new TObjectName(); 22588 resultColumnName.setString(targetColumn.getName()); 22589 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 22590 resultColumnName); 22591 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 22592 relation1.setEffectType(effectType); 22593 relation1.setProcess(process); 22594 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 22595 relation1.addSource(new ResultColumnRelationshipElement(targetColumn)); 22596 } 22597 else { 22598 relation.addSource( 22599 new ResultColumnRelationshipElement(targetColumn)); 22600 } 22601 } 22602 22603 } 22604 } else { 22605 ResultColumn targetColumn = modelFactory 22606 .createSelectSetResultColumn(queryTable, sourceColumn); 22607 22608 DataFlowRelationship combinedQueryRelation = modelFactory 22609 .createDataFlowRelation(); 22610 combinedQueryRelation.setEffectType(effectType); 22611 combinedQueryRelation 22612 .setTarget(new ResultColumnRelationshipElement(targetColumn)); 22613 combinedQueryRelation 22614 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 22615 22616 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 22617 } 22618 } 22619 break; 22620 } else { 22621 boolean flag = false; 22622 22623 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 22624 ResultColumn sourceColumn = selectSetResultSetModel 22625 .getColumns().get(j); 22626 List<String> splits = SQLUtil.parseNames(columnName.toString()); 22627 if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 22628 if (getColumnName(sourceColumn.getName()) 22629 .equalsIgnoreCase(getColumnName(splits.get(0))) 22630 || getColumnName(sourceColumn.getName()) 22631 .equalsIgnoreCase(getColumnName(splits.get(1)))) { 22632 ResultColumn targetColumn = modelFactory 22633 .createSelectSetResultColumn(queryTable, sourceColumn); 22634 22635 DataFlowRelationship combinedQueryRelation = modelFactory 22636 .createDataFlowRelation(); 22637 combinedQueryRelation.setEffectType(effectType); 22638 combinedQueryRelation.setTarget( 22639 new ResultColumnRelationshipElement(targetColumn)); 22640 combinedQueryRelation.addSource( 22641 new ResultColumnRelationshipElement(sourceColumn)); 22642 22643 relation.addSource( 22644 new ResultColumnRelationshipElement(targetColumn)); 22645 flag = true; 22646 break; 22647 } 22648 } 22649 else if (getColumnName(sourceColumn.getName()) 22650 .equalsIgnoreCase(getColumnName(columnName))) { 22651 ResultColumn targetColumn = modelFactory 22652 .createSelectSetResultColumn(queryTable, sourceColumn); 22653 22654 DataFlowRelationship combinedQueryRelation = modelFactory 22655 .createDataFlowRelation(); 22656 combinedQueryRelation.setEffectType(effectType); 22657 combinedQueryRelation 22658 .setTarget(new ResultColumnRelationshipElement(targetColumn)); 22659 combinedQueryRelation 22660 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 22661 22662 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 22663 flag = true; 22664 break; 22665 } 22666 else if (sourceColumn instanceof SelectSetResultColumn && ((SelectSetResultColumn)sourceColumn).getAliasSet().size() > 1) { 22667 for (String alias : ((SelectSetResultColumn)sourceColumn).getAliasSet()) { 22668 if (getColumnName(alias).equalsIgnoreCase(getColumnName(columnName))) { 22669 ResultColumn targetColumn = modelFactory 22670 .createSelectSetResultColumn(queryTable, sourceColumn); 22671 22672 DataFlowRelationship combinedQueryRelation = modelFactory 22673 .createDataFlowRelation(); 22674 combinedQueryRelation.setEffectType(effectType); 22675 combinedQueryRelation.setTarget( 22676 new ResultColumnRelationshipElement(targetColumn)); 22677 combinedQueryRelation.addSource( 22678 new ResultColumnRelationshipElement(sourceColumn)); 22679 22680 relation.addSource( 22681 new ResultColumnRelationshipElement(targetColumn)); 22682 flag = true; 22683 break; 22684 } 22685 } 22686 if (flag) { 22687 break; 22688 } 22689 } 22690 } 22691 22692 if (flag) { 22693 break; 22694 } else if (columnIndex != -1) { 22695 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 22696 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 22697 if (!sourceColumn.getStarLinkColumns().isEmpty()) { 22698 if (cteColumns != null) { 22699 if (j < cteColumns.size()) { 22700 ResultColumn targetColumn = queryTable.getColumns().get(j); 22701 relation.addSource( 22702 new ResultColumnRelationshipElement(targetColumn)); 22703 } 22704 } 22705 else { 22706 if(sourceColumn.hasStarLinkColumn()) { 22707 for (TObjectName linkColumn : sourceColumn.getStarLinkColumnList()) { 22708 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 22709 ResultColumn targetColumn = modelFactory 22710 .createSelectSetResultColumn(queryTable, sourceColumn); 22711 22712 DataFlowRelationship combinedQueryRelation = modelFactory 22713 .createDataFlowRelation(); 22714 combinedQueryRelation.setEffectType(effectType); 22715 combinedQueryRelation.setTarget( 22716 new ResultColumnRelationshipElement(targetColumn, linkColumn)); 22717 combinedQueryRelation.addSource( 22718 new ResultColumnRelationshipElement(sourceColumn)); 22719 22720 relation.addSource( 22721 new ResultColumnRelationshipElement(targetColumn, linkColumn)); 22722 flag = true; 22723 break; 22724 } 22725 } 22726 } 22727 22728 if(!flag) { 22729 ResultColumn targetColumn = modelFactory 22730 .createSelectSetResultColumn(queryTable, sourceColumn); 22731 22732 DataFlowRelationship combinedQueryRelation = modelFactory 22733 .createDataFlowRelation(); 22734 combinedQueryRelation.setEffectType(effectType); 22735 combinedQueryRelation.setTarget( 22736 new ResultColumnRelationshipElement(targetColumn)); 22737 combinedQueryRelation.addSource( 22738 new ResultColumnRelationshipElement(sourceColumn)); 22739 22740 relation.addSource( 22741 new ResultColumnRelationshipElement(targetColumn)); 22742 } 22743 } 22744 flag = true; 22745 break; 22746 } 22747 } 22748 } 22749 22750 if (flag) { 22751 break; 22752 } else if (columnIndex < selectSetResultSetModel.getColumns().size() 22753 && columnIndex != -1) { 22754 ResultColumn sourceColumn = selectSetResultSetModel.getColumns() 22755 .get(columnIndex); 22756 if (cteColumns != null) { 22757 boolean flag1 = false; 22758 for (ResultColumn targetColumn : queryTable.getColumns()) { 22759 if (getColumnName(targetColumn.getName()) 22760 .equalsIgnoreCase(getColumnName(columnName))) { 22761 relation.addSource( 22762 new ResultColumnRelationshipElement(targetColumn)); 22763 flag1 = true; 22764 break; 22765 } 22766 } 22767 if (!flag1 && columnIndex < cteColumns.size()){ 22768 ResultColumn targetColumn = queryTable.getColumns() 22769 .get(columnIndex); 22770 relation.addSource( 22771 new ResultColumnRelationshipElement(targetColumn)); 22772 } 22773 } else { 22774 ResultColumn targetColumn = modelFactory 22775 .createSelectSetResultColumn(queryTable, sourceColumn); 22776 22777 DataFlowRelationship combinedQueryRelation = modelFactory 22778 .createDataFlowRelation(); 22779 combinedQueryRelation.setEffectType(effectType); 22780 combinedQueryRelation 22781 .setTarget(new ResultColumnRelationshipElement(targetColumn)); 22782 combinedQueryRelation 22783 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 22784 22785 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 22786 } 22787 flag = true; 22788 break; 22789 } 22790 22791 if (flag) { 22792 break; 22793 } 22794 } 22795 } else if (cteColumns != null) { 22796 if (getColumnName(columnName).equals("*")) { 22797 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 22798 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 22799 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 22800 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 22801 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 22802 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 22803 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 22804 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 22805 } 22806 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22807 22808 if (columnName.getSourceColumn() != null) { 22809 Object model = modelManager.getModel(columnName.getSourceColumn()); 22810 if (model instanceof ResultColumn && ((ResultColumn)model).getResultSet().isDetermined()) { 22811 resultSet.getColumns().clear(); 22812 } 22813 } else if (columnName.getSourceTable() != null) { 22814 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 22815 if (tableModel instanceof Table && ((Table)tableModel).isDetermined()) { 22816 resultSet.getColumns().clear(); 22817 } 22818 } 22819 } 22820 } 22821 22822 for (int j = 0; j < cteColumns.size(); j++) { 22823 ResultColumn targetColumn = queryTable.getColumns().get(j); 22824 22825 if (exceptColumnList != null) { 22826 boolean flag = false; 22827 for (TObjectName objectName : exceptColumnList) { 22828 if (getColumnName(objectName) 22829 .equals(getColumnName(targetColumn.getName()))) { 22830 flag = true; 22831 break; 22832 } 22833 } 22834 if (flag) { 22835 continue; 22836 } 22837 } 22838 22839 if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) { 22840 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName()); 22841 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22842 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName())); 22843 Transform transform = new Transform(); 22844 transform.setType(Transform.EXPRESSION); 22845 TObjectName expression = new TObjectName(); 22846 expression.setString(expr.first); 22847 transform.setCode(expression); 22848 resultColumn.setTransform(transform); 22849 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 22850 } else { 22851 if(!replaceAsIdentifierMap.isEmpty()) { 22852 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 22853 TObjectName resultColumnName = new TObjectName(); 22854 resultColumnName.setString(targetColumn.getName()); 22855 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 22856 resultColumnName); 22857 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 22858 relation1.setEffectType(effectType); 22859 relation1.setProcess(process); 22860 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 22861 relation1.addSource(new ResultColumnRelationshipElement(targetColumn)); 22862 } 22863 else { 22864 relation.addSource( 22865 new ResultColumnRelationshipElement(targetColumn)); 22866 } 22867 } 22868 } 22869 break; 22870 } else { 22871 boolean flag = false; 22872 22873 for (int j = 0; j < cteColumns.size(); j++) { 22874 TObjectName sourceColumn = cteColumns.getObjectName(j); 22875 22876 if (getColumnName(sourceColumn).equalsIgnoreCase(getColumnName(columnName))) { 22877 ResultColumn targetColumn = queryTable.getColumns().get(j); 22878 22879 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 22880 flag = true; 22881 break; 22882 } 22883 } 22884 22885 if (flag) { 22886 break; 22887 } 22888 } 22889 } 22890 22891 if (columnName.getSourceColumn() != null) { 22892 Object model = modelManager.getModel(columnName.getSourceColumn()); 22893 if (model instanceof ResultColumn) { 22894 ResultColumn resultColumn = (ResultColumn) model; 22895 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 22896 } 22897 } else if (columnName.getSourceTable() != null) { 22898 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 22899 if (tableModel instanceof Table) { 22900 Object model = modelManager 22901 .getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName)); 22902 if (model instanceof TableColumn) { 22903 relation.addSource(new TableColumnRelationshipElement((TableColumn) model)); 22904 } 22905 } 22906 } 22907 } else { 22908 List<ResultColumn> columns = queryTable.getColumns(); 22909 if (getColumnName(columnName).equals("*")) { 22910 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 22911 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 22912 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 22913 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 22914 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 22915 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 22916 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 22917 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 22918 } 22919 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22920 if(queryTable.isDetermined()) { 22921 resultSet.getColumns().clear(); 22922 } 22923 } 22924 } 22925 22926 int index = 0; 22927 for (int j = 0; j < queryTable.getColumns().size(); j++) { 22928 ResultColumn targetColumn = queryTable.getColumns().get(j); 22929 if (exceptColumnList != null) { 22930 boolean flag = false; 22931 for (TObjectName objectName : exceptColumnList) { 22932 if (getColumnName(objectName) 22933 .equals(getColumnName(targetColumn.getName()))) { 22934 flag = true; 22935 break; 22936 } 22937 } 22938 if (flag) { 22939 continue; 22940 } 22941 } 22942 22943 if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) { 22944 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName()); 22945 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 22946 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName())); 22947 Transform transform = new Transform(); 22948 transform.setType(Transform.EXPRESSION); 22949 TObjectName expression = new TObjectName(); 22950 expression.setString(expr.first); 22951 transform.setCode(expression); 22952 resultColumn.setTransform(transform); 22953 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 22954 } else { 22955 if(!replaceAsIdentifierMap.isEmpty()) { 22956 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 22957 TObjectName resultColumnName = new TObjectName(); 22958 resultColumnName.setString(targetColumn.getName()); 22959 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 22960 resultColumnName); 22961 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 22962 relation1.setEffectType(effectType); 22963 relation1.setProcess(process); 22964 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 22965 relation1.addSource(new ResultColumnRelationshipElement(targetColumn)); 22966 } 22967 else { 22968 relation.addSource( 22969 new ResultColumnRelationshipElement(targetColumn)); 22970 } 22971 } 22972 index++; 22973 } 22974 } else { 22975 if (table.getCTE() != null) { 22976 22977 if (modelObject instanceof TableColumn) { 22978 Table modelTable = ((TableColumn) modelObject).getTable(); 22979 if (modelTable.getSubType() == SubType.unnest) { 22980 boolean find = false; 22981 for (k = 0; k < columns.size(); k++) { 22982 ResultColumn column = columns.get(k); 22983 if (column.isStruct()) { 22984 List<String> names = SQLUtil.parseNames(column.getName()); 22985 for (String name : names) { 22986 if (getColumnName(name).equals(getColumnName(columnName))) { 22987 DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation(); 22988 unnestRelation.setEffectType(effectType); 22989 unnestRelation.setProcess(process); 22990 unnestRelation.addSource(new ResultColumnRelationshipElement( 22991 column, columnName)); 22992 TObjectName unnestTableColumnName = new TObjectName(); 22993 unnestTableColumnName.setString(names.get(names.size()-1)); 22994 TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true); 22995 unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn)); 22996 find = true; 22997 } 22998 } 22999 List<String> names1 = SQLUtil.parseNames(column.getName()); 23000 if (names.size() == 1 && names1.size() >= 1) { 23001 for (String name : names1) { 23002 if (getColumnName(name) 23003 .equals(getColumnName(column.getName()))) { 23004 DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation(); 23005 unnestRelation.setEffectType(effectType); 23006 unnestRelation.setProcess(process); 23007 unnestRelation.addSource(new ResultColumnRelationshipElement( 23008 column, columnName)); 23009 TObjectName unnestTableColumnName = new TObjectName(); 23010 unnestTableColumnName.setString(names1.get(names.size()-1)); 23011 TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true); 23012 unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn)); 23013 find = true; 23014 } 23015 } 23016 } 23017 } 23018 } 23019 if (find) { 23020 modelTable.getColumns().remove(modelObject); 23021 break; 23022 } 23023 } 23024 } 23025 23026 for (k = 0; k < columns.size(); k++) { 23027 ResultColumn column = columns.get(k); 23028 if ("*".equals(column.getName())) { 23029 if (!containsStarColumn(column, columnName)) { 23030 column.bindStarLinkColumn(columnName); 23031 } 23032 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23033 } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 23034 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23035 if (!column.equals(modelObject)) { 23036 relation.addSource( 23037 new ResultColumnRelationshipElement(column, columnName)); 23038 } 23039 break; 23040 } else if(column.isStruct()) { 23041 List<String> names = SQLUtil.parseNames(column.getName()); 23042 for(String name: names) { 23043 if (getColumnName(name) 23044 .equals(getColumnName(columnName))) { 23045 relation.addSource( 23046 new ResultColumnRelationshipElement(column, columnName)); 23047 } 23048 } 23049 List<String> names1 = SQLUtil.parseNames(column.getName()); 23050 if (names.size() == 1 && names1.size() >= 1) { 23051 for(String name: names1) { 23052 if (getColumnName(name) 23053 .equals(getColumnName(column.getName()))) { 23054 relation.addSource( 23055 new ResultColumnRelationshipElement(column, columnName)); 23056 } 23057 } 23058 } 23059 } 23060 } 23061 } else if (table.getAliasClause() != null 23062 && table.getAliasClause().getColumns() != null) { 23063 for (k = 0; k < columns.size(); k++) { 23064 ResultColumn column = columns.get(k); 23065 List<String> splits = SQLUtil.parseNames(columnName.toString()); 23066 if ("*".equals(column.getName())) { 23067 if (!containsStarColumn(column, columnName)) { 23068 column.bindStarLinkColumn(columnName); 23069 } 23070 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23071 } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 23072 if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)), 23073 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23074 if (!column.equals(modelObject)) { 23075 relation.addSource(new ResultColumnRelationshipElement(column, 23076 columnName)); 23077 } 23078 break; 23079 } 23080 } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 23081 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23082 if (!column.equals(modelObject)) { 23083 relation.addSource( 23084 new ResultColumnRelationshipElement(column, columnName)); 23085 } 23086 break; 23087 } 23088 } 23089 } else if (table.getSubquery() != null || (table.getTableExpr() != null 23090 && table.getTableExpr().getSubQuery() != null)) { 23091 TSelectSqlStatement select = table.getSubquery(); 23092 if (select == null) { 23093 select = table.getTableExpr().getSubQuery(); 23094 } 23095 if (columnName.getSourceTable() != null) { 23096 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 23097 appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName, 23098 tableModel); 23099 } else if (columnName.getObjectToken() != null 23100 && !SQLUtil.isEmpty(table.getAliasName())) { 23101 if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(), 23102 table.getAliasName())) { 23103 Object tableModel = modelManager.getModel(table); 23104 appendResultColumnRelationSource(modelObject, relation, columnIndex, 23105 columnName, tableModel); 23106 } 23107 } else if(columns!=null) { 23108 for (k = 0; k < columns.size(); k++) { 23109 ResultColumn column = columns.get(k); 23110 List<String> splits = SQLUtil.parseNames(columnName.toString()); 23111 if ("*".equals(column.getName())) { 23112 if (!containsStarColumn(column, columnName)) { 23113 column.bindStarLinkColumn(columnName); 23114 } 23115 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23116 } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 23117 if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)), 23118 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23119 if (!column.equals(modelObject)) { 23120 relation.addSource(new ResultColumnRelationshipElement(column, 23121 columnName)); 23122 } 23123 break; 23124 } 23125 } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 23126 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23127 if (!column.equals(modelObject)) { 23128 relation.addSource( 23129 new ResultColumnRelationshipElement(column, columnName)); 23130 } 23131 break; 23132 } 23133 } 23134 } 23135 } else if (table.getOutputMerge() != null) { 23136 if (columnName.getSourceColumn() != null) { 23137 Object model = modelManager.getModel(columnName.getSourceColumn()); 23138 if (model instanceof ResultColumn) { 23139 ResultColumn resultColumn = (ResultColumn) model; 23140 if ("*".equals(resultColumn.getName()) 23141 && !containsStarColumn(resultColumn, columnName)) { 23142 resultColumn.bindStarLinkColumn(columnName); 23143 } 23144 relation.addSource( 23145 new ResultColumnRelationshipElement(resultColumn, columnName)); 23146 } 23147 } else if (columnName.getSourceTable() != null) { 23148 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 23149 appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName, 23150 tableModel); 23151 } else if (columnName.getObjectToken() != null 23152 && !SQLUtil.isEmpty(table.getAliasName())) { 23153 if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(), 23154 table.getAliasName())) { 23155 Object tableModel = modelManager.getModel(table); 23156 appendResultColumnRelationSource(modelObject, relation, columnIndex, 23157 columnName, tableModel); 23158 } 23159 } 23160 } 23161 } 23162 } 23163 } 23164 } 23165 } 23166 if (relation.getSources().size() == 0 && isKeyword(columnName)) { 23167 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 23168 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, columnName, true); 23169 relation.addSource(new ConstantRelationshipElement(constantColumn)); 23170 } 23171 23172 if (relation.getSources().size() > 0) { 23173 for (RelationshipElement<?> sourceItem: relation.getSources()) { 23174 Object source = sourceItem.getElement(); 23175 ImpactRelationship impactRelation = null; 23176 if (source instanceof ResultColumn 23177 && !((ResultColumn) source).getResultSet().getRelationRows().getHoldRelations().isEmpty()) { 23178 impactRelation = modelFactory.createImpactRelation(); 23179 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 23180 ((ResultColumn) source).getResultSet().getRelationRows())); 23181 impactRelation.setEffectType(effectType); 23182 } else if (source instanceof TableColumn 23183 && !((TableColumn) source).getTable().getRelationRows().getHoldRelations().isEmpty()) { 23184 impactRelation = modelFactory.createImpactRelation(); 23185 impactRelation.addSource(new RelationRowsRelationshipElement<TableRelationRows>( 23186 ((TableColumn) source).getTable().getRelationRows())); 23187 impactRelation.setEffectType(effectType);; 23188 } 23189 23190 if (impactRelation == null) { 23191 continue; 23192 } 23193 23194 Object target = relation.getTarget().getElement(); 23195 if (target instanceof ResultColumn) { 23196 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 23197 ((ResultColumn) target).getResultSet().getRelationRows())); 23198 } else if (target instanceof TableColumn) { 23199 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 23200 ((TableColumn) target).getTable().getRelationRows())); 23201 } 23202 23203 if (impactRelation.getSources().iterator().next().getElement() == impactRelation.getTarget().getElement()) { 23204 modelManager.removeRelation(impactRelation); 23205 } 23206 } 23207 } 23208 } 23209 return relation; 23210 } 23211 23212 private boolean isNotInProcedure(Table table) { 23213 TStoredProcedureSqlStatement stmt = getProcedureParent(stmtStack.peek()); 23214 Procedure procedure = this.modelFactory.createProcedure(stmt); 23215 if(procedure!=null && procedure.getName().equals(table.getParent())){ 23216 return false; 23217 } 23218 return true; 23219 } 23220 23221 private boolean hasJoin(TCustomSqlStatement stmt) { 23222 if (stmt.getJoins() == null || stmt.getJoins().size() == 0) 23223 return false; 23224 if (stmt.getJoins().size() > 1) { 23225 return true; 23226 } 23227 TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems(); 23228 if (joinItems == null || joinItems.size() == 0) { 23229 return false; 23230 } 23231 return true; 23232 } 23233 23234 private boolean isInQuery(TSelectSqlStatement query, TResultColumn column) { 23235 if(query == null) 23236 return false; 23237 TResultColumnList columns = query.getResultColumnList(); 23238 if (columns != null) { 23239 for (int i = 0; i < columns.size(); i++) { 23240 if (columns.getResultColumn(i).equals(column)) { 23241 return true; 23242 } 23243 } 23244 } 23245 return false; 23246 } 23247 23248 private void appendResultColumnRelationSource(Object modelObject, DataFlowRelationship relation, int columnIndex, 23249 TObjectName columnName, Object tableModel) { 23250 if (tableModel instanceof Table) { 23251 Object model = modelManager.getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName)); 23252 if (model instanceof TableColumn) { 23253 relation.addSource(new TableColumnRelationshipElement((TableColumn) model)); 23254 } 23255 } else if (tableModel instanceof ResultSet) { 23256 List<ResultColumn> queryColumns = ((ResultSet) tableModel).getColumns(); 23257 boolean flag = false; 23258 for (int l = 0; l < queryColumns.size(); l++) { 23259 ResultColumn column = queryColumns.get(l); 23260 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 23261 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23262 if (!column.equals(modelObject)) { 23263 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23264 flag = true; 23265 } 23266 break; 23267 } 23268 } 23269 if (!flag) { 23270 for (int l = 0; l < queryColumns.size(); l++) { 23271 ResultColumn column = queryColumns.get(l); 23272 if ("*".equals(column.getName())) { 23273 if (!containsStarColumn(column, columnName)) { 23274 column.bindStarLinkColumn(columnName); 23275 } 23276 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23277 flag = true; 23278 break; 23279 } 23280 } 23281 } 23282 if (!flag && columnIndex < queryColumns.size() && columnIndex != -1) { 23283 relation.addSource(new ResultColumnRelationshipElement(queryColumns.get(columnIndex), columnName)); 23284 } 23285 } 23286 } 23287 23288 private boolean isApplyJoin(TCustomSqlStatement stmt) { 23289 if (stmt.getJoins() == null || stmt.getJoins().size() == 0) 23290 return false; 23291 TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems(); 23292 if (joinItems == null || joinItems.size() == 0) { 23293 return false; 23294 } 23295 if (joinItems.getJoinItem(0).getJoinType() == EJoinType.crossapply 23296 || joinItems.getJoinItem(0).getJoinType() == EJoinType.outerapply) 23297 return true; 23298 return false; 23299 } 23300 23301 private boolean containsStarColumn(ResultColumn resultColumn, TObjectName columnName) { 23302 String targetColumnName = getColumnName(columnName); 23303 if (resultColumn.hasStarLinkColumn()) { 23304 return resultColumn.getStarLinkColumns().containsKey(targetColumnName); 23305 } 23306 return false; 23307 } 23308 23309 private void analyzeAggregate(TFunctionCall function, TExpression expr) { 23310 TCustomSqlStatement stmt = stmtStack.peek(); 23311 ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList()); 23312 if (resultSet == null) { 23313 return; 23314 } 23315 23316 if (expr != null) { 23317 columnsInExpr visitor = new columnsInExpr(); 23318 expr.inOrderTraverse(visitor); 23319 List<TObjectName> objectNames = visitor.getObjectNames(); 23320 for (int j = 0; j < objectNames.size(); j++) { 23321 TObjectName columnName = objectNames.get(j); 23322 23323 if (columnName.getDbObjectType() == EDbObjectType.variable) { 23324 continue; 23325 } 23326 23327 if (columnName.getColumnNameOnly().startsWith("@") 23328 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 23329 continue; 23330 } 23331 23332 if (columnName.getColumnNameOnly().startsWith(":") 23333 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 23334 continue; 23335 } 23336 23337 Object targetModel0 = modelManager.getModel(function.getFunctionName()); 23338 if (targetModel0 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 23339 Function functionModel = (Function) modelManager.getModel(function); 23340 if (functionModel.getColumns().size() == 1) { 23341 targetModel0 = ((Function) functionModel).getColumns().get(0); 23342 } 23343 } 23344 if (!(targetModel0 instanceof ResultColumn)) { 23345 continue; 23346 } 23347 ResultColumn targetResultColumn0 = (ResultColumn) targetModel0; 23348 AbstractRelationship relation = modelFactory.createRecordSetRelation(); 23349 relation.setEffectType(EffectType.function); 23350 relation.setFunction(function.getFunctionName().toString()); 23351 relation.setTarget(new ResultColumnRelationshipElement(targetResultColumn0)); 23352 TTable table = modelManager.getTable(stmt, columnName); 23353 if (table != null) { 23354 if (modelManager.getModel(table) instanceof Table) { 23355 Table tableModel = (Table) modelManager.getModel(table); 23356 if (tableModel != null) { 23357 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false); 23358 if (columnModel != null) { 23359 relation.addSource( 23360 new TableColumnRelationshipElement(columnModel, columnName.getLocation())); 23361 } 23362 } 23363 } else if (modelManager.getModel(table) instanceof QueryTable) { 23364 Object model = modelManager.getModel(columnName.getSourceColumn()); 23365 if (model instanceof ResultColumn) { 23366 ResultColumn resultColumn = (ResultColumn) model; 23367 if (resultColumn != null) { 23368 relation.addSource( 23369 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 23370 } 23371 } 23372 } 23373 } 23374 } 23375 23376 List<TParseTreeNode> functions = visitor.getFunctions(); 23377 for (int j = 0; j < functions.size(); j++) { 23378 TParseTreeNode functionObj = functions.get(j); 23379 Object functionModel = modelManager.getModel(functionObj); 23380 if (functionModel == null) { 23381 functionModel = createFunction(functionObj); 23382 } 23383 if (functionModel instanceof Function) { 23384 Object targetModel1 = modelManager.getModel(function.getFunctionName()); 23385 if (targetModel1 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 23386 Function functionModel1 = (Function) modelManager.getModel(function); 23387 if (functionModel1.getColumns().size() == 1) { 23388 targetModel1 = ((Function) functionModel1).getColumns().get(0); 23389 } 23390 } 23391 if (!(targetModel1 instanceof ResultColumn)) { 23392 continue; 23393 } 23394 ResultColumn targetRC_func = (ResultColumn) targetModel1; 23395 AbstractRelationship relation; 23396 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 23397 // relation = modelFactory.createDataFlowRelation(); 23398 relation = modelFactory.createRecordSetRelation(); 23399 } else { 23400 relation = modelFactory.createRecordSetRelation(); 23401 } 23402 relation.setEffectType(EffectType.function); 23403 relation.setFunction(function.getFunctionName().toString()); 23404 relation.setTarget(new ResultColumnRelationshipElement(targetRC_func)); 23405 23406 if (functionObj instanceof TFunctionCall) { 23407 ResultColumn resultColumn = (ResultColumn) modelManager 23408 .getModel(((TFunctionCall) functionObj).getFunctionName()); 23409 if (resultColumn != null) { 23410 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn, 23411 ((TFunctionCall) functionObj).getFunctionName().getLocation()); 23412 relation.addSource(element); 23413 } 23414 } 23415 if (functionObj instanceof TCaseExpression) { 23416 ResultColumn resultColumn = (ResultColumn) modelManager 23417 .getModel(((TCaseExpression) functionObj).getWhenClauseItemList()); 23418 if (resultColumn != null) { 23419 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn); 23420 relation.addSource(element); 23421 } 23422 } 23423 } else if (functionModel instanceof Table) { 23424 Object targetModel2 = modelManager.getModel(function.getFunctionName()); 23425 if (targetModel2 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 23426 Function functionModel1 = (Function) modelManager.getModel(function); 23427 if (functionModel1.getColumns().size() == 1) { 23428 targetModel2 = ((Function) functionModel1).getColumns().get(0); 23429 } 23430 } 23431 if (!(targetModel2 instanceof ResultColumn)) { 23432 continue; 23433 } 23434 ResultColumn targetRC_table = (ResultColumn) targetModel2; 23435 TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel, 23436 function.getFunctionName(), false); 23437 AbstractRelationship relation; 23438 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 23439 // relation = modelFactory.createDataFlowRelation(); 23440 relation = modelFactory.createRecordSetRelation(); 23441 } else { 23442 relation = modelFactory.createRecordSetRelation(); 23443 } 23444 relation.setEffectType(EffectType.function); 23445 relation.setFunction(function.getFunctionName().toString()); 23446 relation.setTarget(new ResultColumnRelationshipElement(targetRC_table)); 23447 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 23448 relation.addSource(element); 23449 } 23450 } 23451 } 23452 23453 if (expr == null || "COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 23454 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString()) 23455 // https://e.gitee.com/gudusoft/issues/list?issue=I4L5EO 23456 // 对于非 count() 函数,当有group by clause时, RelationRows 不参与indirect dataflow, 23457 // 让位与group by clause中的column. 23458 || ((TSelectSqlStatement) stmt).getGroupByClause() == null) { 23459 TTableList tables = stmt.getTables(); 23460 if (tables != null) { 23461 for (int i = 0; i < tables.size(); i++) { 23462 TTable table = tables.getTable(i); 23463 if (modelManager.getModel(table) == null && table.getSubquery() == null) { 23464 modelFactory.createTable(table); 23465 } 23466 if (modelManager.getModel(table) instanceof Table) { 23467 Object targetModel3 = modelManager.getModel(function.getFunctionName()); 23468 if (targetModel3 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 23469 Function functionModel = (Function) modelManager.getModel(function); 23470 if (functionModel.getColumns().size() == 1) { 23471 targetModel3 = functionModel.getColumns().get(0); 23472 } 23473 } 23474 if (!(targetModel3 instanceof ResultColumn)) { 23475 continue; 23476 } 23477 ResultColumn targetRC_tbl = (ResultColumn) targetModel3; 23478 Table tableModel = (Table) modelManager.getModel(table); 23479 AbstractRelationship relation; 23480 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 23481 // relation = modelFactory.createDataFlowRelation(); 23482 relation = modelFactory.createRecordSetRelation(); 23483 } else { 23484 relation = modelFactory.createRecordSetRelation(); 23485 } 23486 relation.setEffectType(EffectType.function); 23487 relation.setFunction(function.getFunctionName().toString()); 23488 relation.setTarget(new ResultColumnRelationshipElement(targetRC_tbl)); 23489 23490 if (relation instanceof DataFlowRelationship && option.isShowCountTableColumn()) { 23491 List<TExpression> expressions = new ArrayList<TExpression>(); 23492 getFunctionExpressions(expressions, new ArrayList<TExpression>(), function); 23493 for (int j = 0; j < expressions.size(); j++) { 23494 columnsInExpr visitor = new columnsInExpr(); 23495 expressions.get(j).inOrderTraverse(visitor); 23496 List<TObjectName> objectNames = visitor.getObjectNames(); 23497 if (objectNames != null) { 23498 for (TObjectName columnName : objectNames) { 23499 TTable tempTable = modelManager.getTable(stmt, columnName); 23500 if (table.equals(tempTable)) { 23501 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, 23502 columnName, false); 23503 TableColumnRelationshipElement element = new TableColumnRelationshipElement( 23504 tableColumn); 23505 relation.addSource(element); 23506 } 23507 } 23508 } 23509 } 23510 } 23511 if (relation.getSources().size() == 0) { 23512 RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<TableRelationRows>( 23513 tableModel.getRelationRows()); 23514 relation.addSource(element); 23515 } 23516 } else if (modelManager.getModel(table) instanceof QueryTable) { 23517 Object targetModel4 = modelManager.getModel(function.getFunctionName()); 23518 if (targetModel4 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 23519 Function functionModel = (Function) modelManager.getModel(function); 23520 targetModel4 = functionModel.getColumns().get(0); 23521 } 23522 if (!(targetModel4 instanceof ResultColumn)) { 23523 continue; 23524 } 23525 ResultColumn targetRC_qt = (ResultColumn) targetModel4; 23526 QueryTable tableModel = (QueryTable) modelManager.getModel(table); 23527 AbstractRelationship relation; 23528 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 23529 // relation = modelFactory.createDataFlowRelation(); 23530 relation = modelFactory.createRecordSetRelation(); 23531 } else { 23532 relation = modelFactory.createRecordSetRelation(); 23533 } 23534 relation.setEffectType(EffectType.function); 23535 relation.setFunction(function.getFunctionName().toString()); 23536 relation.setTarget(new ResultColumnRelationshipElement(targetRC_qt)); 23537 RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<ResultSetRelationRows>( 23538 tableModel.getRelationRows()); 23539 relation.addSource(element); 23540 } 23541 } 23542 } 23543 } 23544 23545 if (stmt.getWhereClause() == null || stmt.getWhereClause().getCondition() == null) { 23546 return; 23547 } 23548 23549 columnsInExpr visitor = new columnsInExpr(); 23550 stmt.getWhereClause().getCondition().inOrderTraverse(visitor); 23551 List<TObjectName> objectNames = visitor.getObjectNames(); 23552 for (int j = 0; j < objectNames.size(); j++) { 23553 TObjectName columnName = objectNames.get(j); 23554 if (columnName.getDbObjectType() == EDbObjectType.variable) { 23555 Variable tableModel; 23556 if (columnName.toString().indexOf(".") != -1) { 23557 List<String> splits = SQLUtil.parseNames(columnName.toString()); 23558 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 23559 } else { 23560 tableModel = modelFactory.createVariable(columnName); 23561 } 23562 tableModel.setCreateTable(true); 23563 tableModel.setSubType(SubType.record); 23564 TObjectName variableProperties = new TObjectName(); 23565 variableProperties.setString("*"); 23566 modelFactory.createTableColumn(tableModel, variableProperties, true); 23567 } 23568 23569// if (columnName.getColumnNameOnly().startsWith("@") 23570// && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 23571// continue; 23572// } 23573// 23574// if (columnName.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 23575// continue; 23576// } 23577 23578 Object targetModel5 = modelManager.getModel(function.getFunctionName()); 23579 if (targetModel5 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 23580 Function functionModel = (Function) modelManager.getModel(function); 23581 if (functionModel.getColumns().size() == 1) { 23582 targetModel5 = functionModel.getColumns().get(0); 23583 } 23584 } 23585 if (!(targetModel5 instanceof ResultColumn)) { 23586 continue; 23587 } 23588 AbstractRelationship relation = modelFactory.createRecordSetRelation(); 23589 relation.setEffectType(EffectType.function); 23590 relation.setFunction(function.getFunctionName().toString()); 23591 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) targetModel5)); 23592 23593 TTable table = modelManager.getTable(stmt, columnName); 23594 if (table != null) { 23595 if (modelManager.getModel(table) instanceof Table) { 23596 Table tableModel = (Table) modelManager.getModel(table); 23597 if (tableModel != null) { 23598 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false); 23599 if(columnModel == null) { 23600 continue; 23601 } 23602 relation.addSource( 23603 new TableColumnRelationshipElement(columnModel, columnName.getLocation())); 23604 } 23605 } else if (modelManager.getModel(table) instanceof QueryTable) { 23606 Object model = modelManager.getModel(columnName.getSourceColumn()); 23607 if (model instanceof ResultColumn) { 23608 ResultColumn resultColumn = (ResultColumn) model; 23609 if (resultColumn != null) { 23610 relation.addSource( 23611 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 23612 } 23613 } 23614 } 23615 } 23616 } 23617 } 23618 } 23619 23620 private void analyzeFilterCondition(Object modelObject, TExpression expr, EJoinType joinType, 23621 JoinClauseType joinClauseType, EffectType effectType) { 23622 if (expr == null) { 23623 return; 23624 } 23625 23626 TCustomSqlStatement stmt = stmtStack.peek(); 23627 23628 columnsInExpr visitor = new columnsInExpr(); 23629 expr.inOrderTraverse(visitor); 23630 23631 List<TObjectName> objectNames = visitor.getObjectNames(); 23632 List<TParseTreeNode> functions = visitor.getFunctions(); 23633 List<TResultColumn> resultColumns = visitor.getResultColumns(); 23634 List<TParseTreeNode> constants = visitor.getConstants(); 23635 23636 ImpactRelationship relation = modelFactory.createImpactRelation(); 23637 relation.setEffectType(effectType); 23638 relation.setJoinClauseType(joinClauseType); 23639 if (modelObject instanceof ResultColumn) { 23640 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 23641 } else { 23642 ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList()); 23643 if (resultSet == null && stmt instanceof TUpdateSqlStatement) { 23644 resultSet = (ResultSet) modelManager.getModel(stmt); 23645 } 23646 if (resultSet == null && stmt instanceof TMergeSqlStatement) { 23647 TSelectSqlStatement subquery = ((TMergeSqlStatement) stmt).getUsingTable().getSubquery(); 23648 if (subquery != null) { 23649 resultSet = (ResultSet) modelManager.getModel(((TMergeSqlStatement) stmt).getUsingTable()); 23650 } 23651 else { 23652 resultSet = modelFactory.createQueryTable(((TMergeSqlStatement) stmt).getUsingTable()); 23653 } 23654 } 23655 if (resultSet != null) { 23656 relation.setTarget( 23657 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 23658 } 23659 if (stmt instanceof TDeleteSqlStatement) { 23660 Table table = (Table) modelManager.getModel(((TDeleteSqlStatement) stmt).getTargetTable()); 23661 if (table != null) { 23662 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(table.getRelationRows())); 23663 } 23664 } 23665 } 23666 if (relation.getTarget() != null) { 23667 23668 if (constants != null && constants.size() > 0) { 23669 if (option.isShowConstantTable()) { 23670 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 23671 for (int i = 0; i < constants.size(); i++) { 23672 TParseTreeNode constant = constants.get(i); 23673 if (constant instanceof TConstant) { 23674 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 23675 (TConstant) constant); 23676 relation.addSource(new ConstantRelationshipElement(constantColumn)); 23677 } else if (constant instanceof TObjectName) { 23678 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 23679 (TObjectName) constant, false); 23680 if(constantColumn == null) { 23681 continue; 23682 } 23683 relation.addSource(new ConstantRelationshipElement(constantColumn)); 23684 } 23685 } 23686 } 23687 } 23688 23689 for (int j = 0; j < objectNames.size(); j++) { 23690 TObjectName columnName = objectNames.get(j); 23691 if (columnName.getDbObjectType() == EDbObjectType.variable) { 23692 Variable variable = modelFactory.createVariable(columnName); 23693 variable.setSubType(SubType.record); 23694 if (variable.getColumns().isEmpty()) { 23695 TObjectName variableProperties = new TObjectName(); 23696 variableProperties.setString("*"); 23697 modelFactory.createTableColumn(variable, variableProperties, true); 23698 } 23699 relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0), columnName.getLocation())); 23700 continue; 23701 } 23702 23703 if (columnName.getColumnNameOnly().startsWith("@") 23704 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 23705 continue; 23706 } 23707 23708 if (columnName.getColumnNameOnly().startsWith(":") 23709 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 23710 continue; 23711 } 23712 23713 TTable table = modelManager.getTable(stmt, columnName); 23714 23715 if (table == null) { 23716 table = columnName.getSourceTable(); 23717 } 23718 23719 if (table == null && stmt.tables != null) { 23720 for (int k = 0; k < stmt.tables.size(); k++) { 23721 if (table != null) 23722 break; 23723 23724 TTable tTable = stmt.tables.getTable(k); 23725 if (tTable.getTableType().name().startsWith("open")) { 23726 continue; 23727 } else if (getTableLinkedColumns(tTable) != null && getTableLinkedColumns(tTable).size() > 0) { 23728 for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) { 23729 TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z); 23730 if ("*".equals(getColumnName(refer))) 23731 continue; 23732 if (getColumnName(refer).equals(getColumnName(columnName))) { 23733 table = tTable; 23734 break; 23735 } 23736 } 23737 } else if (columnName.getTableToken() != null 23738 && (columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getName()) 23739 || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) { 23740 table = tTable; 23741 break; 23742 } 23743 } 23744 23745 if (table == null) { 23746 for (int k = 0; k < stmt.tables.size(); k++) { 23747 if (table != null) 23748 break; 23749 23750 TTable tTable = stmt.tables.getTable(k); 23751 Object model = ModelBindingManager.get().getModel(tTable); 23752 if (model instanceof Table) { 23753 Table tableModel = (Table) model; 23754 for (int z = 0; tableModel.getColumns() != null 23755 && z < tableModel.getColumns().size(); z++) { 23756 TableColumn refer = tableModel.getColumns().get(z); 23757 if (getColumnName(refer.getName()).equals(getColumnName(columnName))) { 23758 table = tTable; 23759 break; 23760 } 23761 if (refer.hasStarLinkColumn()) { 23762 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 23763 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 23764 table = tTable; 23765 break; 23766 } 23767 } 23768 } 23769 } 23770 } else if (model instanceof QueryTable) { 23771 QueryTable tableModel = (QueryTable) model; 23772 for (int z = 0; tableModel.getColumns() != null 23773 && z < tableModel.getColumns().size(); z++) { 23774 ResultColumn refer = tableModel.getColumns().get(z); 23775 if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals( 23776 DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) { 23777 table = tTable; 23778 break; 23779 } 23780 if (refer.hasStarLinkColumn()) { 23781 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 23782 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 23783 table = tTable; 23784 break; 23785 } 23786 } 23787 } 23788 } 23789 } 23790 } 23791 } 23792 } 23793 23794 if (table == null && stmt.tables != null && stmt.tables.size() != 0 23795 && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) { 23796 23797 if (modelManager.getModel(stmt) instanceof ResultSet) { 23798 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt); 23799 boolean find = false; 23800 for (ResultColumn resultColumn : resultSetModel.getColumns()) { 23801 if(resultColumn.equals(modelObject)) { 23802 continue; 23803 } 23804 if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) { 23805 if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) { 23806 if (resultColumn.getColumnObject() != null) { 23807 int startToken = resultColumn.getColumnObject().getStartToken().posinlist; 23808 int endToken = resultColumn.getColumnObject().getEndToken().posinlist; 23809 if (columnName.getStartToken().posinlist >= startToken 23810 && columnName.getEndToken().posinlist <= endToken) { 23811 continue; 23812 } 23813 } 23814 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 23815 find = true; 23816 break; 23817 } 23818 } 23819 } 23820 if (find) { 23821 continue; 23822 } 23823 } 23824 23825 TObjectName pseudoTableName = new TObjectName(); 23826 // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl) 23827 // Otherwise fall back to default pseudo table name 23828 String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName); 23829 pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column"); 23830 Table pseudoTable = modelFactory.createTableByName(pseudoTableName); 23831 pseudoTable.setPseudo(true); 23832 TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true); 23833 23834 // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col), 23835 // add the pseudo table column as source 23836 if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) { 23837 relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn)); 23838 } 23839 23840 if (isLinkOrphanColumnToFirstTable()) { 23841 TTable orphanTable = stmt.tables.getTable(0); 23842 table = stmt.tables.getTable(0); 23843 Object tableModel = modelManager.getModel(table); 23844 if (tableModel == null) { 23845 tableModel = modelFactory.createTable(orphanTable); 23846 } 23847 if (tableModel instanceof Table) { 23848 modelFactory.createTableColumn((Table) tableModel, columnName, false); 23849 ErrorInfo errorInfo = new ErrorInfo(); 23850 errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN); 23851 errorInfo.setErrorMessage("Link orphan column [" + columnName.toString() 23852 + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]"); 23853 errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo, 23854 columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 23855 errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo, 23856 columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(), 23857 ModelBindingManager.getGlobalHash())); 23858 errorInfo.fillInfo(this); 23859 errorInfos.add(errorInfo); 23860 } 23861 } 23862 } 23863 23864 if (table != null) { 23865 if (modelManager.getModel(table) instanceof Table) { 23866 Table tableModel = (Table) modelManager.getModel(table); 23867 if (tableModel != null) { 23868 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false); 23869 if(columnModel!=null) { 23870 TableColumnRelationshipElement element = new TableColumnRelationshipElement(columnModel, 23871 columnName.getLocation()); 23872 relation.addSource(element); 23873 } 23874 } 23875 } else if (modelManager.getModel(table) instanceof QueryTable) { 23876 QueryTable tableModel = (QueryTable)modelManager.getModel(table); 23877 if (table.getSubquery() != null && table.getSubquery().isCombinedQuery()) { 23878 TSelectSqlStatement subquery = table.getSubquery(); 23879 List<ResultSet> resultSets = new ArrayList<ResultSet>(); 23880 if (!subquery.getLeftStmt().isCombinedQuery()) { 23881 ResultSet sourceResultSet = (ResultSet) modelManager 23882 .getModel(subquery.getLeftStmt().getResultColumnList()); 23883 resultSets.add(sourceResultSet); 23884 } else { 23885 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getLeftStmt()); 23886 resultSets.add(sourceResultSet); 23887 } 23888 23889 if (!subquery.getRightStmt().isCombinedQuery()) { 23890 ResultSet sourceResultSet = (ResultSet) modelManager 23891 .getModel(subquery.getRightStmt().getResultColumnList()); 23892 resultSets.add(sourceResultSet); 23893 } else { 23894 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getRightStmt()); 23895 resultSets.add(sourceResultSet); 23896 } 23897 23898 for (ResultSet sourceResultSet : resultSets) { 23899 if (sourceResultSet != null && columnName.getSourceColumn() != null) { 23900 for (int k = 0; k < sourceResultSet.getColumns().size(); k++) { 23901 if (getColumnName(sourceResultSet.getColumns().get(k).getName()).equals( 23902 getColumnName(columnName.getSourceColumn().getColumnNameOnly()))) { 23903 Set<TObjectName> starLinkColumnSet = sourceResultSet.getColumns().get(k) 23904 .getStarLinkColumns().get(getColumnName(columnName)); 23905 if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) { 23906 ResultColumn column = modelFactory.createResultColumn(sourceResultSet, 23907 starLinkColumnSet.iterator().next(), true); 23908 relation.addSource(new ResultColumnRelationshipElement(column)); 23909 } else { 23910 relation.addSource(new ResultColumnRelationshipElement( 23911 sourceResultSet.getColumns().get(k))); 23912 } 23913 } 23914 } 23915 } 23916 } 23917 } else { 23918 Object model = modelManager.getModel(columnName.getSourceColumn()); 23919 if (model instanceof ResultColumn) { 23920 ResultColumn resultColumn = (ResultColumn) model; 23921 if (resultColumn != null) { 23922 if (resultColumn.hasStarLinkColumn()) { 23923 Set<TObjectName> starLinkColumnSet = resultColumn.getStarLinkColumns() 23924 .get(getColumnName(columnName)); 23925 if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) { 23926 ResultColumn column = modelFactory.createResultColumn( 23927 resultColumn.getResultSet(), starLinkColumnSet.iterator().next(), true); 23928 relation.addSource(new ResultColumnRelationshipElement(column)); 23929 } else { 23930 resultColumn.bindStarLinkColumn(columnName); 23931 ResultColumn column = modelFactory 23932 .createResultColumn(resultColumn.getResultSet(), columnName, true); 23933 relation.addSource(new ResultColumnRelationshipElement(column)); 23934 } 23935 } else { 23936 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement( 23937 resultColumn, columnName.getLocation()); 23938 relation.addSource(element); 23939 } 23940 } 23941 } 23942 else{ 23943 boolean find = false; 23944 for (int i = 0; i < tableModel.getColumns().size(); i++) { 23945 ResultColumn resultColumn = tableModel.getColumns().get(i); 23946 if (DlineageUtil.getIdentifierNormalColumnName(resultColumn.getName()).equals( 23947 DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) { 23948 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement( 23949 resultColumn, columnName.getLocation()); 23950 relation.addSource(element); 23951 find = true; 23952 break; 23953 } 23954 else if (resultColumn.getName().endsWith("*")) { 23955 resultColumn.bindStarLinkColumn(columnName); 23956 } 23957 } 23958 if(!find){ 23959 ResultColumn resultColumn = new ResultColumn(tableModel, columnName); 23960 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement( 23961 resultColumn, columnName.getLocation()); 23962 relation.addSource(element); 23963 } 23964 } 23965 } 23966 } 23967 } 23968 } 23969 23970 for (int j = 0; j < functions.size(); j++) { 23971 TParseTreeNode functionObj = functions.get(j); 23972 Object functionModel = modelManager.getModel(functionObj); 23973 if (functionModel == null) { 23974 functionModel = createFunction(functionObj); 23975 } 23976 if (functionModel instanceof Function) { 23977 if (functionObj instanceof TFunctionCall) { 23978 ResultColumn resultColumn = (ResultColumn) modelManager 23979 .getModel(((TFunctionCall) functionObj).getFunctionName()); 23980 if (resultColumn != null) { 23981 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn, 23982 ((TFunctionCall) functionObj).getFunctionName().getLocation()); 23983 relation.addSource(element); 23984 } 23985 } 23986 if (functionObj instanceof TCaseExpression) { 23987 ResultColumn resultColumn = (ResultColumn) modelManager 23988 .getModel(((TCaseExpression) functionObj).getWhenClauseItemList()); 23989 if (resultColumn != null) { 23990 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn); 23991 relation.addSource(element); 23992 } 23993 } 23994 } else if (functionModel instanceof Table) { 23995 TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel, 23996 ((TFunctionCall) functionObj).getFunctionName(), false); 23997 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 23998 relation.addSource(element); 23999 } 24000 } 24001 24002 for (int j = 0; j < resultColumns.size(); j++) { 24003 TResultColumn resultColumn = resultColumns.get(j); 24004 if (modelManager.getModel(resultColumn) instanceof ResultColumn) { 24005 ResultColumn resultColumnModel = (ResultColumn) modelManager.getModel(resultColumn); 24006 relation.addSource(new ResultColumnRelationshipElement(resultColumnModel, ESqlClause.selectList)); 24007 } 24008 } 24009 } 24010 24011 if (isShowJoin() && joinClauseType != null) { 24012 joinInExpr joinVisitor = new joinInExpr(joinType, joinClauseType, effectType); 24013 expr.inOrderTraverse(joinVisitor); 24014 } 24015 } 24016 24017 public void dispose() { 24018 accessedSubqueries.clear(); 24019 accessedStatements.clear(); 24020 stmtStack.clear(); 24021 viewDDLMap.clear(); 24022 procedureDDLMap.clear(); 24023 structObjectMap.clear(); 24024 appendResultSets.clear(); 24025 appendStarColumns.clear(); 24026 appendTableStarColumns.clear(); 24027 modelManager.DISPLAY_ID.clear(); 24028 modelManager.DISPLAY_NAME.clear(); 24029 tableIds.clear(); 24030 ModelBindingManager.remove(); 24031 } 24032 24033 class joinTreatColumnsInExpr implements IExpressionVisitor { 24034 24035 private List<TObjectName> objectNames = new ArrayList<TObjectName>(); 24036 24037 private TTable table; 24038 24039 public joinTreatColumnsInExpr(TTable table) { 24040 this.table = table; 24041 } 24042 24043 public List<TObjectName> getObjectNames() { 24044 return objectNames; 24045 } 24046 24047 boolean is_compare_condition(EExpressionType t) { 24048 return t == EExpressionType.simple_comparison_t; 24049 } 24050 24051 @Override 24052 public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) { 24053 TExpression expr = (TExpression) pNode; 24054 if (is_compare_condition(expr.getExpressionType())) { 24055 TExpression leftExpr = expr.getLeftOperand(); 24056 columnsInExpr leftVisitor = new columnsInExpr(); 24057 leftExpr.inOrderTraverse(leftVisitor); 24058 List<TObjectName> leftObjectNames = leftVisitor.getObjectNames(); 24059 24060 TExpression rightExpr = expr.getRightOperand(); 24061 columnsInExpr rightVisitor = new columnsInExpr(); 24062 rightExpr.inOrderTraverse(rightVisitor); 24063 List<TObjectName> rightObjectNames = rightVisitor.getObjectNames(); 24064 24065 if (!leftObjectNames.isEmpty() && !rightObjectNames.isEmpty()) { 24066 for (TObjectName column : leftObjectNames) { 24067 if (column.getSourceTable() != null && column.getSourceTable().equals(table)) { 24068 objectNames.add(column); 24069 return false; 24070 } 24071 } 24072 for (TObjectName column : rightObjectNames) { 24073 if (column.getSourceTable() != null && column.getSourceTable().equals(table)) { 24074 objectNames.add(column); 24075 return false; 24076 } 24077 } 24078 } 24079 return false; 24080 } 24081 return true; 24082 } 24083 } 24084 24085 class columnsInExpr implements IExpressionVisitor { 24086 24087 private List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>(); 24088 private List<TObjectName> objectNames = new ArrayList<TObjectName>(); 24089 private List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>(); 24090 private List<TResultColumn> resultColumns = new ArrayList<TResultColumn>(); 24091 private List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>(); 24092 private boolean skipFunction = false; 24093 24094 public void setSkipFunction(boolean skipFunction) { 24095 this.skipFunction = skipFunction; 24096 } 24097 24098 public List<TParseTreeNode> getFunctions() { 24099 return functions; 24100 } 24101 24102 public List<TSelectSqlStatement> getSubquerys() { 24103 return subquerys; 24104 } 24105 24106 public List<TParseTreeNode> getConstants() { 24107 return constants; 24108 } 24109 24110 public List<TObjectName> getObjectNames() { 24111 return objectNames; 24112 } 24113 24114 public List<TResultColumn> getResultColumns() { 24115 return resultColumns; 24116 } 24117 24118 @Override 24119 public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) { 24120 TExpression lcexpr = (TExpression) pNode; 24121 // Handle named argument expressions (e.g., "INPUT => value" in Snowflake FLATTEN) 24122 // The left operand is the parameter name, NOT a column reference. 24123 // Only traverse the right operand (the value). 24124 if (lcexpr.getExpressionType() == EExpressionType.assignment_t) { 24125 // Skip left operand (parameter name) - only traverse right operand (value) 24126 if (lcexpr.getRightOperand() != null) { 24127 lcexpr.getRightOperand().inOrderTraverse(this); 24128 } 24129 return false; // Don't continue default traversal 24130 } 24131 if (lcexpr.getExpressionType() == EExpressionType.simple_constant_t) { 24132 if (lcexpr.getConstantOperand() != null) { 24133 if(lcexpr.getConstantOperand().getInt64_expression()!=null 24134 && lcexpr.getConstantOperand().getInt64_expression().getExpressionType() == EExpressionType.function_t) { 24135 lcexpr.getConstantOperand().getInt64_expression().inOrderTraverse(this); 24136 } 24137 else { 24138 constants.add(lcexpr.getConstantOperand()); 24139 } 24140 } 24141 } else if (lcexpr.getExpressionType() == EExpressionType.array_t) { 24142 if(lcexpr.getObjectOperand()!=null) { 24143 TObjectName object = lcexpr.getObjectOperand(); 24144 objectNames.add(object); 24145 } else if (lcexpr.getExprList() != null) { 24146 for (int j = 0; j < lcexpr.getExprList().size(); j++) { 24147 TExpression expr = lcexpr.getExprList().getExpression(j); 24148 if (expr != null) 24149 expr.inOrderTraverse(this); 24150 } 24151 } 24152 } else if (lcexpr.getExpressionType() == EExpressionType.simple_object_name_t) { 24153 if (lcexpr.getObjectOperand() != null && !(isBuiltInFunctionName(lcexpr.getObjectOperand()) 24154 && isFromFunction(lcexpr.getObjectOperand()))) { 24155 TObjectName object = lcexpr.getObjectOperand(); 24156 // Skip named argument parameter names (e.g., INPUT in "INPUT => value") 24157 // These are function parameter names, NOT column references 24158 if (object.getObjectType() == TObjectName.ttobjNamedArgParameter) { 24159 // Skip - this is a named argument parameter name 24160 } else if (object.getDbObjectType() == EDbObjectType.column 24161 || object.getDbObjectType() == EDbObjectType.column_alias 24162 || object.getDbObjectType() == EDbObjectType.alias 24163 || object.getDbObjectType() == EDbObjectType.unknown 24164 || object.getDbObjectType() == EDbObjectType.variable) { 24165 objectNames.add(object); 24166 } else if (object.getDbObjectType() == EDbObjectType.notAColumn 24167 || object.getDbObjectType() == EDbObjectType.date_time_part ) { 24168 constants.add(object); 24169 } 24170 } 24171 } else if (lcexpr.getExpressionType() == EExpressionType.between_t) { 24172 if (lcexpr.getBetweenOperand() != null && lcexpr.getBetweenOperand().getObjectOperand() != null) { 24173 TObjectName object = lcexpr.getBetweenOperand().getObjectOperand(); 24174 if (object.getDbObjectType() == EDbObjectType.column 24175 || object.getDbObjectType() == EDbObjectType.column_alias 24176 || object.getDbObjectType() == EDbObjectType.alias 24177 || object.getDbObjectType() == EDbObjectType.unknown 24178 || object.getDbObjectType() == EDbObjectType.variable) { 24179 objectNames.add(object); 24180 } 24181 } 24182 } else if (lcexpr.getExpressionType() == EExpressionType.object_access_t) { 24183 if (lcexpr.getObjectAccess() != null) { 24184 TObjectNameList objects = lcexpr.getObjectAccess().getAttributes(); 24185 TFunctionCall function = lcexpr.getObjectAccess().getObjectExpr().getFunctionCall(); 24186 if (objects != null && function != null) { 24187 for (TObjectName object : objects) { 24188 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 24189 sqlparser.sqltext = "select " + function.getFunctionName().toString() + "." 24190 + object.getColumnNameOnly() + " from " + function.getFunctionName().toString(); 24191 if (sqlparser.parse() == 0) { 24192 TObjectName objectName = sqlparser.sqlstatements.get(0).getResultColumnList() 24193 .getResultColumn(0).getFieldAttr(); 24194 objectNames.add(objectName); 24195 } 24196 } 24197 } 24198 } 24199 } else if (lcexpr.getExpressionType() == EExpressionType.function_t || lcexpr.getExpressionType() == EExpressionType.fieldselection_t) { 24200 TFunctionCall func = lcexpr.getFunctionCall(); 24201 if (func == null) { 24202 return true; 24203 } 24204 if (skipFunction) { 24205 if (func.getArgs() != null) { 24206 for (int k = 0; k < func.getArgs().size(); k++) { 24207 TExpression expr = func.getArgs().getExpression(k); 24208 if (expr != null) 24209 expr.inOrderTraverse(this); 24210 } 24211 } 24212 24213 if (func.getTrimArgument() != null) { 24214 TTrimArgument args = func.getTrimArgument(); 24215 TExpression expr = args.getStringExpression(); 24216 if (expr != null) { 24217 expr.inOrderTraverse(this); 24218 } 24219 expr = args.getTrimCharacter(); 24220 if (expr != null) { 24221 expr.inOrderTraverse(this); 24222 } 24223 } 24224 24225 if (func.getAgainstExpr() != null) { 24226 func.getAgainstExpr().inOrderTraverse(this); 24227 } 24228// if (func.getBetweenExpr() != null) { 24229// func.getBetweenExpr().inOrderTraverse(this); 24230// } 24231 if (func.getExpr1() != null) { 24232 func.getExpr1().inOrderTraverse(this); 24233 } 24234 if (func.getExpr2() != null) { 24235 func.getExpr2().inOrderTraverse(this); 24236 } 24237 if (func.getExpr3() != null) { 24238 func.getExpr3().inOrderTraverse(this); 24239 } 24240 if (func.getParameter() != null) { 24241 func.getParameter().inOrderTraverse(this); 24242 } 24243 } else { 24244 functions.add(func); 24245 } 24246 24247 } else if (lcexpr.getExpressionType() == EExpressionType.case_t) { 24248 TCaseExpression expr = lcexpr.getCaseExpression(); 24249 if (skipFunction) { 24250 TExpression defaultExpr = expr.getElse_expr(); 24251 if (defaultExpr != null) { 24252 defaultExpr.inOrderTraverse(this); 24253 } 24254 TWhenClauseItemList list = expr.getWhenClauseItemList(); 24255 for (int i = 0; i < list.size(); i++) { 24256 TWhenClauseItem element = (TWhenClauseItem) list.getElement(i); 24257 (((TWhenClauseItem) element).getReturn_expr()).inOrderTraverse(this); 24258 24259 } 24260 } else { 24261 functions.add(expr); 24262 } 24263 } else if (lcexpr.getSubQuery() != null) { 24264 TSelectSqlStatement select = lcexpr.getSubQuery(); 24265 analyzeSelectStmt(select); 24266 subquerys.add(select); 24267 if (select.getResultColumnList() != null && select.getResultColumnList().size() > 0) { 24268 for (TResultColumn column : select.getResultColumnList()) { 24269 resultColumns.add(column); 24270 } 24271 } 24272 } 24273 return true; 24274 } 24275 } 24276 24277 class joinInExpr implements IExpressionVisitor { 24278 24279 private EJoinType joinType; 24280 private JoinClauseType joinClauseType; 24281 private EffectType effectType; 24282 24283 public joinInExpr(EJoinType joinType, JoinClauseType joinClauseType, EffectType effectType) { 24284 this.joinType = joinType; 24285 this.joinClauseType = joinClauseType; 24286 this.effectType = effectType; 24287 } 24288 24289 boolean is_compare_condition(EExpressionType t) { 24290 return ((t == EExpressionType.simple_comparison_t) || (t == EExpressionType.group_comparison_t) 24291 || (t == EExpressionType.in_t) || (t == EExpressionType.pattern_matching_t) 24292 || (t == EExpressionType.left_join_t) || (t == EExpressionType.right_join_t)); 24293 } 24294 24295 @Override 24296 public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) { 24297 TExpression expr = (TExpression) pNode; 24298 if (is_compare_condition(expr.getExpressionType())) { 24299 TExpression leftExpr = expr.getLeftOperand(); 24300 columnsInExpr leftVisitor = new columnsInExpr(); 24301 leftExpr.inOrderTraverse(leftVisitor); 24302 List<TObjectName> leftObjectNames = leftVisitor.getObjectNames(); 24303 List<TParseTreeNode> leftObjects = leftVisitor.getFunctions(); 24304 leftObjects.addAll(leftObjectNames); 24305 24306 TExpression rightExpr = expr.getRightOperand(); 24307 columnsInExpr rightVisitor = new columnsInExpr(); 24308 rightExpr.inOrderTraverse(rightVisitor); 24309 List<TObjectName> rightObjectNames = rightVisitor.getObjectNames(); 24310 List<TParseTreeNode> rightObjects = rightVisitor.getFunctions(); 24311 rightObjects.addAll(rightObjectNames); 24312 24313 if (!leftObjects.isEmpty() && !rightObjects.isEmpty()) { 24314 TCustomSqlStatement stmt = stmtStack.peek(); 24315 24316 for (int i = 0; i < leftObjects.size(); i++) { 24317 TParseTreeNode leftObject = leftObjects.get(i); 24318 TTable leftTable = null; 24319 TFunctionCall leftFunction = null; 24320 TObjectName leftObjectName = null; 24321 if (leftObject instanceof TObjectName) { 24322 leftObjectName = (TObjectName)leftObject; 24323 24324 if (leftObjectName.getDbObjectType() == EDbObjectType.variable) { 24325 continue; 24326 } 24327 24328 if (leftObjectName.getColumnNameOnly().startsWith("@") 24329 && (option.getVendor() == EDbVendor.dbvmssql 24330 || option.getVendor() == EDbVendor.dbvazuresql)) { 24331 continue; 24332 } 24333 24334 if (leftObjectName.getColumnNameOnly().startsWith(":") 24335 && (option.getVendor() == EDbVendor.dbvhana 24336 || option.getVendor() == EDbVendor.dbvteradata)) { 24337 continue; 24338 } 24339 24340 leftTable = modelManager.getTable(stmt, leftObjectName); 24341 24342 if (leftTable == null) { 24343 leftTable = leftObjectName.getSourceTable(); 24344 } 24345 24346 if (leftTable == null) { 24347 leftTable = modelManager.guessTable(stmt, leftObjectName); 24348 } 24349 } 24350 else if(leftObject instanceof TFunctionCall){ 24351 leftFunction = (TFunctionCall)leftObject; 24352 } 24353 24354 if (leftTable != null || leftFunction != null) { 24355 for (int j = 0; j < rightObjects.size(); j++) { 24356 JoinRelationship joinRelation = modelFactory.createJoinRelation(); 24357 joinRelation.setEffectType(effectType); 24358 if (joinType != null) { 24359 joinRelation.setJoinType(joinType); 24360 } else { 24361 if (expr.getLeftOperand().isOracleOuterJoin()) { 24362 joinRelation.setJoinType(right); 24363 } else if (expr.getRightOperand().isOracleOuterJoin()) { 24364 joinRelation.setJoinType(EJoinType.left); 24365 } else if (expr.getExpressionType() == EExpressionType.left_join_t) { 24366 joinRelation.setJoinType(EJoinType.left); 24367 } else if (expr.getExpressionType() == EExpressionType.right_join_t) { 24368 joinRelation.setJoinType(right); 24369 } else { 24370 joinRelation.setJoinType(EJoinType.inner); 24371 } 24372 } 24373 24374 joinRelation.setJoinClauseType(joinClauseType); 24375 joinRelation.setJoinCondition(expr.toString()); 24376 24377 24378 if (leftTable != null) { 24379 if (modelManager.getModel(leftTable) instanceof Table) { 24380 Table tableModel = (Table) modelManager.getModel(leftTable); 24381 if (tableModel != null) { 24382 TableColumn columnModel = modelFactory.createTableColumn(tableModel, 24383 leftObjectName, false); 24384 if (columnModel != null) { 24385 joinRelation.addSource(new TableColumnRelationshipElement(columnModel)); 24386 } 24387 } 24388 } else if (modelManager.getModel(leftTable) instanceof QueryTable) { 24389 QueryTable table = (QueryTable) modelManager.getModel(leftTable); 24390 TSelectSqlStatement subquery = table.getTableObject().getSubquery(); 24391 if (subquery != null && subquery.isCombinedQuery()) { 24392 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 24393 leftObjectName); 24394 if (resultColumn != null) { 24395 joinRelation 24396 .addSource(new ResultColumnRelationshipElement(resultColumn)); 24397 } 24398 } else if (leftObjectName.getSourceColumn() != null) { 24399 Object model = modelManager.getModel(leftObjectName); 24400 if (model == null) { 24401 model = modelFactory.createResultColumn(table, leftObjectName); 24402 } 24403 if (model instanceof ResultColumn) { 24404 ResultColumn resultColumn = (ResultColumn) model; 24405 if (resultColumn != null) { 24406 joinRelation.addSource( 24407 new ResultColumnRelationshipElement(resultColumn)); 24408 } 24409 } else if (model instanceof LinkedHashMap) { 24410 String columnName = getColumnNameOnly(leftObjectName.toString()); 24411 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model; 24412 if (resultColumns.containsKey(columnName)) { 24413 ResultColumn resultColumn = resultColumns.get(columnName); 24414 joinRelation.addSource( 24415 new ResultColumnRelationshipElement(resultColumn)); 24416 } 24417 } 24418 } else { 24419 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 24420 leftObjectName); 24421 if (resultColumn != null) { 24422 joinRelation 24423 .addSource(new ResultColumnRelationshipElement(resultColumn)); 24424 } 24425 } 24426 } 24427 } 24428 else if(leftFunction!=null) { 24429 Object functionObj = createFunction(leftFunction); 24430 if(functionObj instanceof Function) { 24431 Function function = (Function)functionObj; 24432 joinRelation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0))); 24433 } 24434 } 24435 24436 TParseTreeNode rightObject = rightObjects.get(j); 24437 if(rightObject instanceof TObjectName) { 24438 TObjectName rightObjectName = (TObjectName)rightObject; 24439 24440 if (rightObjectName.getDbObjectType() == EDbObjectType.variable) { 24441 continue; 24442 } 24443 24444 if (rightObjectName.getColumnNameOnly().startsWith("@") 24445 && (option.getVendor() == EDbVendor.dbvmssql 24446 || option.getVendor() == EDbVendor.dbvazuresql)) { 24447 continue; 24448 } 24449 24450 if (rightObjectName.getColumnNameOnly().startsWith(":") 24451 && (option.getVendor() == EDbVendor.dbvhana 24452 || option.getVendor() == EDbVendor.dbvteradata)) { 24453 continue; 24454 } 24455 24456 TTable rightTable = modelManager.getTable(stmt, rightObjectName); 24457 if (rightTable == null) { 24458 rightTable = rightObjectName.getSourceTable(); 24459 } 24460 24461 if (rightTable == null) { 24462 rightTable = modelManager.guessTable(stmt, rightObjectName); 24463 } 24464 24465 if (modelManager.getModel(rightTable) instanceof Table) { 24466 Table tableModel = (Table) modelManager.getModel(rightTable); 24467 if (tableModel != null) { 24468 TableColumn columnModel = modelFactory.createTableColumn(tableModel, 24469 rightObjectName, false); 24470 if(columnModel != null) { 24471 joinRelation.setTarget(new TableColumnRelationshipElement(columnModel)); 24472 } 24473 } 24474 } else if (modelManager.getModel(rightTable) instanceof QueryTable) { 24475 QueryTable table = (QueryTable) modelManager.getModel(rightTable); 24476 TSelectSqlStatement subquery = table.getTableObject().getSubquery(); 24477 if (subquery != null && subquery.isCombinedQuery()) { 24478 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 24479 rightObjectName); 24480 if (resultColumn != null) { 24481 joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 24482 } 24483 } else if (rightObjectName.getSourceColumn() != null) { 24484 Object model = modelManager.getModel(rightObjectName); 24485 if (model == null) { 24486 model = modelManager 24487 .getModel(rightObjectName.getSourceColumn()); 24488 } 24489 if (model instanceof ResultColumn) { 24490 joinRelation.setTarget(new ResultColumnRelationshipElement((ResultColumn)model)); 24491 } 24492 else if (model instanceof LinkedHashMap) { 24493 String columnName = getColumnNameOnly(rightObjectName.toString()); 24494 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 24495 if (resultColumns.containsKey(columnName)) { 24496 ResultColumn resultColumn = resultColumns.get(columnName); 24497 joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 24498 } 24499 } 24500 } else { 24501 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 24502 rightObjectName); 24503 if (resultColumn != null) { 24504 joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 24505 } 24506 } 24507 } 24508 } 24509 else if(rightObject instanceof TFunctionCall) { 24510 Object functionObj = createFunction(rightObject); 24511 if(functionObj instanceof Function) { 24512 Function function = (Function)functionObj; 24513 joinRelation.setTarget(new ResultColumnRelationshipElement(function.getColumns().get(0))); 24514 } 24515 } 24516 } 24517 } 24518 } 24519 } 24520 } 24521 return true; 24522 } 24523 } 24524 24525 @Deprecated 24526 public static Dataflow getSqlflowJSONModel(dataflow dataflow) { 24527 EDbVendor vendor = ModelBindingManager.getGlobalVendor(); 24528 if(vendor == null) { 24529 throw new IllegalArgumentException("getSqlflowJSONModel(dataflow dataflow) is deprecated, please call method getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor)."); 24530 } 24531 return getSqlflowJSONModel(vendor, dataflow, false); 24532 } 24533 24534 public static Dataflow getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor) { 24535 return getSqlflowJSONModel(vendor, dataflow, false); 24536 } 24537 24538 public static Dataflow getSqlflowJSONModel(EDbVendor vendor, dataflow dataflow, boolean normalizeIdentifier) { 24539 Dataflow model = new Dataflow(); 24540 24541 if (dataflow.getErrors() != null && !dataflow.getErrors().isEmpty()) { 24542 List<Error> errorList = new ArrayList<Error>(); 24543 for (error error : dataflow.getErrors()) { 24544 Error err = new Error(); 24545 err.setErrorMessage(error.getErrorMessage()); 24546 err.setErrorType(error.getErrorType()); 24547 err.setCoordinates(Coordinate.parse(error.getCoordinate())); 24548 err.setFile(err.getFile()); 24549 err.setOriginCoordinates(Coordinate.parse(error.getOriginCoordinate())); 24550 errorList.add(err); 24551 } 24552 model.setErrors(errorList.toArray(new Error[0])); 24553 } 24554 24555 Sqlflow sqlflow = MetadataUtil.convertDataflowToMetadata(vendor, dataflow); 24556 sqlflow.setErrorMessages(null); 24557 model.setDbobjs(sqlflow); 24558 model.setOrientation(dataflow.getOrientation()); 24559 24560 24561 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process> processes = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process>(); 24562 if(dataflow.getProcesses()!=null){ 24563 for(process process: dataflow.getProcesses()){ 24564 gudusoft.gsqlparser.dlineage.dataflow.model.json.Process processModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process(); 24565 processModel.setId(process.getId()); 24566 processModel.setName(process.getName()); 24567 processModel.setProcedureId(process.getProcedureId()); 24568 processModel.setProcedureName(process.getProcedureName()); 24569 processModel.setType(process.getType()); 24570 processModel.setCoordinate(process.getCoordinate()); 24571 processModel.setDatabase(process.getDatabase()); 24572 processModel.setSchema(process.getSchema()); 24573 processModel.setServer(process.getServer()); 24574 processModel.setQueryHashId(process.getQueryHashId()); 24575 if (process.getTransforms() != null && !process.getTransforms().isEmpty()) { 24576 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>(); 24577 for (transform transform : process.getTransforms()) { 24578 gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform(); 24579 item.setCode(transform.getCode()); 24580 item.setType(transform.getType()); 24581 item.setCoordinate(transform.getCoordinate(true)); 24582 transforms.add(item); 24583 } 24584 processModel.setTransforms(transforms 24585 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0])); 24586 } 24587 processes.add(processModel); 24588 } 24589 } 24590 model.setProcesses(processes.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process[0])); 24591 24592 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship> relations = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship>(); 24593 if (dataflow.getRelationships() != null) { 24594 for (relationship relation : dataflow.getRelationships()) { 24595 gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship relationModel; 24596 if (relation.getType().equals("join")) { 24597 gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship joinRelationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship(); 24598 joinRelationModel.setCondition(relation.getCondition()); 24599 joinRelationModel.setJoinType(relation.getJoinType()); 24600 joinRelationModel.setClause(relation.getClause()); 24601 relationModel = joinRelationModel; 24602 } else { 24603 relationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship(); 24604 } 24605 24606 relationModel.setId(relation.getId()); 24607 relationModel.setProcessId(relation.getProcessId()); 24608 relationModel.setProcessType(relation.getProcessType()); 24609 relationModel.setType(relation.getType()); 24610 relationModel.setEffectType(relation.getEffectType()); 24611 relationModel.setPartition(relation.getPartition()); 24612 relationModel.setFunction(relation.getFunction()); 24613 relationModel.setProcedureId(relation.getProcedureId()); 24614 relationModel.setSqlHash(relation.getSqlHash()); 24615 relationModel.setCondition(relation.getCondition()); 24616 relationModel.setSqlComment(relation.getSqlComment()); 24617 relationModel.setTimestampMax(relation.getTimestampMax()); 24618 relationModel.setTimestampMin(relation.getTimestampMin()); 24619 if (Boolean.TRUE.equals(relation.getBuiltIn())) { 24620 relationModel.setBuiltIn(relation.getBuiltIn()); 24621 } 24622 relationModel.setCallStmt(relation.getCallStmt()); 24623 relationModel.setCallCoordinate(relation.getCallCoordinate()); 24624 24625 if (relation.getTarget() != null && relation.getSources() != null && !relation.getSources().isEmpty()) { 24626 { 24627 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 24628 targetColumn target = relation.getTarget(); 24629 if (normalizeIdentifier) { 24630 targetModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, target.getColumn())); 24631 targetModel.setParentName( 24632 SQLUtil.getIdentifierNormalTableName(vendor, target.getParent_name())); 24633 targetModel.setTargetName( 24634 SQLUtil.getIdentifierNormalColumnName(vendor, target.getTarget_name())); 24635 } else { 24636 targetModel.setColumn(target.getColumn()); 24637 targetModel.setParentName(target.getParent_name()); 24638 targetModel.setTargetName(target.getTarget_name()); 24639 } 24640 targetModel.setId(target.getId()); 24641 targetModel.setTargetId(target.getTarget_id()); 24642 targetModel.setParentId(target.getParent_id()); 24643 targetModel.setCoordinates(Coordinate.parse(target.getCoordinate())); 24644 targetModel.setFunction(target.getFunction()); 24645 targetModel.setType(target.getType()); 24646 relationModel.setTarget(targetModel); 24647 } 24648 24649 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>(); 24650 for (sourceColumn source : relation.getSources()) { 24651 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 24652 if (normalizeIdentifier) { 24653 sourceModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, source.getColumn())); 24654 sourceModel.setParentName( 24655 SQLUtil.getIdentifierNormalTableName(vendor, source.getParent_name())); 24656 sourceModel.setSourceName( 24657 SQLUtil.getIdentifierNormalColumnName(vendor, source.getSource_name())); 24658 } else { 24659 sourceModel.setColumn(source.getColumn()); 24660 sourceModel.setParentName(source.getParent_name()); 24661 sourceModel.setSourceName(source.getSource_name()); 24662 } 24663 sourceModel.setColumnType(source.getColumn_type()); 24664 sourceModel.setId(source.getId()); 24665 sourceModel.setParentId(source.getParent_id()); 24666 sourceModel.setSourceId(source.getSource_id()); 24667 sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate())); 24668 sourceModel.setClauseType(source.getClauseType()); 24669 sourceModel.setType(source.getType()); 24670 sourceModels.add(sourceModel); 24671 if (source.getTransforms() != null && !source.getTransforms().isEmpty()) { 24672 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>(); 24673 for (transform transform : source.getTransforms()) { 24674 gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform(); 24675 item.setCode(transform.getCode()); 24676 item.setType(transform.getType()); 24677 item.setCoordinate(transform.getCoordinate(true)); 24678 transforms.add(item); 24679 } 24680 sourceModel.setTransforms(transforms 24681 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0])); 24682 } 24683 24684 if (source.getCandidateParents() != null && !source.getCandidateParents().isEmpty()) { 24685 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable> candidateParents = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable>(); 24686 for (candidateTable candidateTable : source.getCandidateParents()) { 24687 gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable(); 24688 item.setId(candidateTable.getId()); 24689 if (normalizeIdentifier) { 24690 item.setName( 24691 SQLUtil.getIdentifierNormalTableName(vendor, candidateTable.getName())); 24692 } else { 24693 item.setName(candidateTable.getName()); 24694 } 24695 candidateParents.add(item); 24696 } 24697 sourceModel.setCandidateParents(candidateParents 24698 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable[0])); 24699 } 24700 } 24701 relationModel.setSources(sourceModels 24702 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0])); 24703 relations.add(relationModel); 24704 } else if (relation.getCaller() != null && relation.getCallees() != null 24705 && !relation.getCallees().isEmpty()) { 24706 { 24707 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 24708 targetColumn target = relation.getCaller(); 24709 if (normalizeIdentifier) { 24710 targetModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, target.getName())); 24711 } else { 24712 targetModel.setName(target.getName()); 24713 } 24714 targetModel.setId(target.getId()); 24715 targetModel.setCoordinates(Coordinate.parse(target.getCoordinate())); 24716 targetModel.setType(target.getType()); 24717 relationModel.setCaller(targetModel); 24718 } 24719 24720 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>(); 24721 for (sourceColumn source : relation.getCallees()) { 24722 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 24723 if (normalizeIdentifier) { 24724 sourceModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, source.getName())); 24725 } else { 24726 sourceModel.setName(source.getName()); 24727 } 24728 sourceModel.setId(source.getId()); 24729 sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate())); 24730 sourceModel.setType(source.getType()); 24731 sourceModels.add(sourceModel); 24732 } 24733 relationModel.setCallees(sourceModels 24734 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0])); 24735 relations.add(relationModel); 24736 } 24737 } 24738 } 24739 model.setRelationships(relations.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship[0])); 24740 return model; 24741 } 24742 24743 public static String getVersion() { 24744 return "3.1.4"; 24745 } 24746 24747 public static String getReleaseDate() { 24748 return "2023-03-04"; 24749 } 24750 24751 public static void main(String[] args) { 24752 if (args.length < 1) { 24753 System.out.println( 24754 "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]"); 24755 System.out.println("/f: Option, specify the sql file path to analyze fdd relation."); 24756 System.out.println("/d: Option, specify the sql directory path to analyze fdd relation."); 24757 System.out.println("/j: Option, analyze the join relation."); 24758 System.out.println("/s: Option, simple output, ignore the intermediate results."); 24759 System.out.println("/i: Option, ignore all result sets."); 24760 System.out.println("/traceView: Option, analyze the source tables of views."); 24761 System.out.println("/text: Option, print the plain text format output."); 24762 System.out.println("/json: Option, print the json format output."); 24763 System.out.println( 24764 "/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"); 24765 System.out.println("/o: Option, write the output stream to the specified file."); 24766 System.out.println("/log: Option, generate a dataflow.log file to log information."); 24767 return; 24768 } 24769 24770 File sqlFiles = null; 24771 24772 List<String> argList = Arrays.asList(args); 24773 24774 if (argList.indexOf("/version") != -1) { 24775 System.out.println("Version: " + DataFlowAnalyzer.getVersion()); 24776 System.out.println("Release Date: " + DataFlowAnalyzer.getReleaseDate()); 24777 return; 24778 } 24779 24780 if (argList.indexOf("/f") != -1 && argList.size() > argList.indexOf("/f") + 1) { 24781 sqlFiles = new File(args[argList.indexOf("/f") + 1]); 24782 if (!sqlFiles.exists() || !sqlFiles.isFile()) { 24783 System.out.println(sqlFiles + " is not a valid file."); 24784 return; 24785 } 24786 } else if (argList.indexOf("/d") != -1 && argList.size() > argList.indexOf("/d") + 1) { 24787 sqlFiles = new File(args[argList.indexOf("/d") + 1]); 24788 if (!sqlFiles.exists() || !sqlFiles.isDirectory()) { 24789 System.out.println(sqlFiles + " is not a valid directory."); 24790 return; 24791 } 24792 } else { 24793 System.out.println("Please specify a sql file path or directory path to analyze dlineage."); 24794 return; 24795 } 24796 24797 EDbVendor vendor = EDbVendor.dbvoracle; 24798 24799 int index = argList.indexOf("/t"); 24800 24801 if (index != -1 && args.length > index + 1) { 24802 vendor = TGSqlParser.getDBVendorByName(args[index + 1]); 24803 } 24804 24805 String outputFile = null; 24806 24807 index = argList.indexOf("/o"); 24808 24809 if (index != -1 && args.length > index + 1) { 24810 outputFile = args[index + 1]; 24811 } 24812 24813 FileOutputStream writer = null; 24814 if (outputFile != null) { 24815 try { 24816 writer = new FileOutputStream(outputFile); 24817 System.setOut(new PrintStream(writer)); 24818 } catch (FileNotFoundException e) { 24819 logger.error("output file is not found.", e); 24820 } 24821 } 24822 24823 boolean simple = argList.indexOf("/s") != -1; 24824 boolean ignoreResultSets = argList.indexOf("/i") != -1; 24825 boolean showJoin = argList.indexOf("/j") != -1; 24826 boolean textFormat = false; 24827 boolean jsonFormat = false; 24828 if (simple) { 24829 textFormat = argList.indexOf("/text") != -1; 24830 } 24831 24832 boolean traceView = argList.indexOf("/traceView") != -1; 24833 if (traceView) { 24834 simple = true; 24835 } 24836 24837 jsonFormat = argList.indexOf("/json") != -1; 24838 24839 DataFlowAnalyzer dlineage = new DataFlowAnalyzer(sqlFiles, vendor, simple); 24840 24841 dlineage.setShowJoin(showJoin); 24842 dlineage.setIgnoreRecordSet(ignoreResultSets); 24843 // dlineage.setShowImplicitSchema(true); 24844 24845 if (simple && !jsonFormat) { 24846 dlineage.setTextFormat(textFormat); 24847 } 24848 24849 String result = dlineage.generateDataFlow(); 24850 24851// dataflow dataflow = ProcessUtility.generateTableLevelLineage(dlineage, dlineage.getDataFlow()); 24852// System.out.println(result); 24853 24854 if (jsonFormat) { 24855 // Map jsonResult = new LinkedHashMap(); 24856 Dataflow model = getSqlflowJSONModel(vendor, dlineage.getDataFlow(), true); 24857 // jsonResult.put("data", BeanUtils.bean2Map(model)); 24858 result = JSON.toJSONString(model); 24859 } else if (traceView) { 24860 result = dlineage.traceView(); 24861 } 24862 24863 if (result != null) { 24864 System.out.println(result); 24865 24866 if (writer != null && result.length() < 1024 * 1024) { 24867 System.err.println(result); 24868 } 24869 } 24870 24871 try { 24872 if (writer != null) { 24873 writer.close(); 24874 } 24875 } catch (IOException e) { 24876 logger.error("close writer failed.", e); 24877 } 24878 24879 boolean log = argList.indexOf("/log") != -1; 24880 24881 PrintStream systemSteam = System.err; 24882 ByteArrayOutputStream sw = new ByteArrayOutputStream(); 24883 PrintStream pw = new PrintStream(sw); 24884 System.setErr(pw); 24885 24886 24887 List<ErrorInfo> errors = dlineage.getErrorMessages(); 24888 if (!errors.isEmpty()) { 24889 System.err.println("Error log:\n"); 24890 for (int i = 0; i < errors.size(); i++) { 24891 System.err.println(errors.get(i).getErrorMessage()); 24892 } 24893 } 24894 24895 if (sw != null) { 24896 String errorMessage = sw.toString().trim(); 24897 if (errorMessage.length() > 0) { 24898 if (log) { 24899 try { 24900 pw = new PrintStream(new File(".", "dataflow.log")); 24901 pw.print(errorMessage); 24902 } catch (FileNotFoundException e) { 24903 logger.error("error log file is not found.", e); 24904 } 24905 } 24906 24907 System.setErr(systemSteam); 24908 System.err.println(errorMessage); 24909 } 24910 } 24911 } 24912 24913 public List<ErrorInfo> getErrorMessages() { 24914 return errorInfos; 24915 } 24916 24917 public String traceView() { 24918 StringBuilder buffer = new StringBuilder(); 24919 dataflow dataflow = this.getDataFlow(); 24920 Map<table, Set<table>> traceViewMap = new LinkedHashMap<table, Set<table>>(); 24921 if (dataflow != null && dataflow.getViews() != null) { 24922 List<relationship> relations = dataflow.getRelationships(); 24923 Map<String, table> viewMap = new HashMap<String, table>(); 24924 Map<String, table> tableMap = new HashMap<String, table>(); 24925 for (table view : dataflow.getViews()) { 24926 viewMap.put(view.getId(), view); 24927 tableMap.put(view.getId(), view); 24928 } 24929 for (table table : dataflow.getTables()) { 24930 tableMap.put(table.getId(), table); 24931 } 24932 for (relationship relation : relations) { 24933 if (!RelationshipType.fdd.name().equals(relation.getType())) { 24934 continue; 24935 } 24936 String parentId = relation.getTarget().getParent_id(); 24937 if (viewMap.containsKey(parentId)) { 24938 if (!traceViewMap.containsKey(viewMap.get(parentId))) { 24939 traceViewMap.put(viewMap.get(parentId), new LinkedHashSet<table>()); 24940 } 24941 24942 for (sourceColumn sourceColumn : relation.getSources()) { 24943 traceViewMap.get(viewMap.get(parentId)).add(tableMap.get(sourceColumn.getParent_id())); 24944 } 24945 } 24946 } 24947 24948 Map<table, Set<table>> viewTableMap = new LinkedHashMap<table, Set<table>>(); 24949 for (table view : traceViewMap.keySet()) { 24950 Set<table> tables = new LinkedHashSet<table>(); 24951 traverseViewSourceTables(tables, view, traceViewMap); 24952 viewTableMap.put(view, tables); 24953 } 24954 24955 for (table view : viewTableMap.keySet()) { 24956 buffer.append(view.getFullName()); 24957 for (table table : viewTableMap.get(view)) { 24958 buffer.append(",").append(table.getFullName()); 24959 } 24960 buffer.append(System.getProperty("line.separator")); 24961 } 24962 } 24963 return buffer.toString().trim(); 24964 } 24965 24966 private void traverseViewSourceTables(Set<table> tables, table view, Map<table, Set<table>> traceViewMap) { 24967 Set<table> sourceTables = traceViewMap.get(view); 24968 for (table sourceTable : sourceTables) { 24969 if (sourceTable.isTable()) { 24970 tables.add(sourceTable); 24971 } else if (sourceTable.isView()) { 24972 traverseViewSourceTables(tables, sourceTable, traceViewMap); 24973 } 24974 } 24975 } 24976 24977 protected List<SqlInfo> convertSQL(EDbVendor vendor, String json) { 24978 List<SqlInfo> sqlInfos = new ArrayList<SqlInfo>(); 24979 List sqlContents = (List) JSON.parseObject(json); 24980 for (int j = 0; j < sqlContents.size(); j++) { 24981 Map sqlContent = (Map) sqlContents.get(j); 24982 String sql = (String) sqlContent.get("sql"); 24983 String fileName = (String) sqlContent.get("fileName"); 24984 String filePath = (String) sqlContent.get("filePath"); 24985 if (sql != null && sql.trim().startsWith("{")) { 24986 if (sql.indexOf("createdBy") != -1) { 24987 if (this.sqlenv == null) { 24988 TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(), 24989 option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql); 24990 if (sqlenvs != null && sqlenvs.length > 0) { 24991 this.sqlenv = sqlenvs[0]; 24992 } 24993 } 24994 if (sql.toLowerCase().indexOf("sqldep") != -1 || sql.toLowerCase().indexOf("grabit") != -1) { 24995 Map queryObject = (Map) JSON.parseObject(sql); 24996 List querys = (List) queryObject.get("queries"); 24997 if (querys != null) { 24998 for (int i = 0; i < querys.size(); i++) { 24999 Map object = (Map) querys.get(i); 25000 SqlInfo info = new SqlInfo(); 25001 info.setSql(JSON.toJSONString(object)); 25002 info.setFileName(fileName); 25003 info.setFilePath(filePath); 25004 info.setOriginIndex(i); 25005 sqlInfos.add(info); 25006 } 25007 queryObject.remove("queries"); 25008 SqlInfo info = new SqlInfo(); 25009 info.setSql(JSON.toJSONString(queryObject)); 25010 info.setFileName(fileName); 25011 info.setFilePath(filePath); 25012 info.setOriginIndex(querys.size()); 25013 sqlInfos.add(info); 25014 } else { 25015 SqlInfo info = new SqlInfo(); 25016 info.setSql(JSON.toJSONString(queryObject)); 25017 info.setFileName(fileName); 25018 info.setFilePath(filePath); 25019 info.setOriginIndex(0); 25020 sqlInfos.add(info); 25021 } 25022 } else if (sql.toLowerCase().indexOf("sqlflow") != -1) { 25023 Map sqlflow = (Map) JSON.parseObject(sql); 25024 List<Map> servers = (List<Map>) sqlflow.get("servers"); 25025 if (servers != null) { 25026 for (Map queryObject : servers) { 25027 String name = (String) queryObject.get("name"); 25028 String dbVendor = (String) queryObject.get("dbVendor"); 25029 List querys = (List) queryObject.get("queries"); 25030 if (querys != null) { 25031 for (int i = 0; i < querys.size(); i++) { 25032 Map object = (Map) querys.get(i); 25033 SqlInfo info = new SqlInfo(); 25034 info.setSql(JSON.toJSONString(object)); 25035 info.setFileName(fileName); 25036 info.setFilePath(filePath); 25037 info.setOriginIndex(i); 25038 info.setDbVendor(dbVendor); 25039 info.setServer(name); 25040 sqlInfos.add(info); 25041 } 25042 queryObject.remove("queries"); 25043 Map serverObject = new IndexedLinkedHashMap(); 25044 serverObject.put("createdBy", sqlflow.get("createdBy")); 25045 serverObject.put("servers", Arrays.asList(queryObject)); 25046 SqlInfo info = new SqlInfo(); 25047 info.setSql(JSON.toJSONString(serverObject)); 25048 info.setFileName(fileName); 25049 info.setFilePath(filePath); 25050 info.setOriginIndex(querys.size()); 25051 info.setDbVendor(dbVendor); 25052 info.setServer(filePath); 25053 sqlInfos.add(info); 25054 } else { 25055 SqlInfo info = new SqlInfo(); 25056 info.setSql(JSON.toJSONString(queryObject)); 25057 info.setFileName(fileName); 25058 info.setFilePath(filePath); 25059 info.setOriginIndex(0); 25060 sqlInfos.add(info); 25061 } 25062 } 25063 } 25064 25065 List<Map> errorMessages = (List<Map>) sqlflow.get("errorMessages"); 25066 if(errorMessages!=null && !errorMessages.isEmpty()) { 25067 for(Map error: errorMessages){ 25068 ErrorInfo errorInfo = new ErrorInfo(); 25069 errorInfo.setErrorType(ErrorInfo.METADATA_ERROR); 25070 errorInfo.setErrorMessage((String)error.get("errorMessage")); 25071 errorInfo.setFileName(fileName); 25072 errorInfo.setFilePath(filePath); 25073 errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L, 25074 ModelBindingManager.getGlobalHash())); 25075 errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L, 25076 ModelBindingManager.getGlobalHash())); 25077 errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L)); 25078 errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L)); 25079 metadataErrors.add(errorInfo); 25080 } 25081 } 25082 } 25083 } 25084 } else if (sql != null) { 25085 SqlInfo info = new SqlInfo(); 25086 info.setSql(sql); 25087 info.setFileName(fileName); 25088 info.setFilePath(filePath); 25089 info.setOriginIndex(0); 25090 sqlInfos.add(info); 25091 } 25092 } 25093 return sqlInfos; 25094 } 25095 25096 public void setTextFormat(boolean textFormat) { 25097 option.setTextFormat(textFormat); 25098 } 25099 25100 public boolean isBuiltInFunctionName(TObjectName object) { 25101 if (object == null || object.getGsqlparser() == null) 25102 return false; 25103 try { 25104 EDbVendor vendor = object.getGsqlparser().getDbVendor(); 25105 if (vendor == EDbVendor.dbvteradata) { 25106 boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(object.toString().toUpperCase()); 25107 if (result) { 25108 return true; 25109 } 25110 } 25111 25112 List<String> versions = functionChecker.getAvailableDbVersions(vendor); 25113 if (versions != null && versions.size() > 0) { 25114 for (int i = 0; i < versions.size(); i++) { 25115 boolean result = functionChecker.isBuiltInFunction(object.toString(), 25116 object.getGsqlparser().getDbVendor(), versions.get(i)); 25117 if (result) { 25118 return result; 25119 } 25120 } 25121 25122 // boolean result = 25123 // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString()); 25124 // if (result) { 25125 // return true; 25126 // } 25127 } 25128 } catch (Exception e) { 25129 } 25130 25131 return false; 25132 } 25133 25134 public boolean isBuiltInFunctionName(String functionName) { 25135 if (functionName == null) 25136 return false; 25137 try { 25138 EDbVendor vendor = getOption().getVendor(); 25139 if (vendor == EDbVendor.dbvteradata) { 25140 boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(functionName.toUpperCase()); 25141 if (result) { 25142 return true; 25143 } 25144 } 25145 25146 List<String> versions = functionChecker.getAvailableDbVersions(vendor); 25147 if (versions != null && versions.size() > 0) { 25148 for (int i = 0; i < versions.size(); i++) { 25149 boolean result = functionChecker.isBuiltInFunction(functionName.toUpperCase(), 25150 vendor, versions.get(i)); 25151 if (result) { 25152 return result; 25153 } 25154 } 25155 25156 // boolean result = 25157 // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString()); 25158 // if (result) { 25159 // return true; 25160 // } 25161 } 25162 } catch (Exception e) { 25163 } 25164 25165 return false; 25166 } 25167 25168 public boolean isKeyword(TObjectName object) { 25169 if (object == null || object.getGsqlparser() == null) 25170 return false; 25171 try { 25172 EDbVendor vendor = object.getGsqlparser().getDbVendor(); 25173 25174 List<String> versions = keywordChecker.getAvailableDbVersions(vendor); 25175 if (versions != null && versions.size() > 0) { 25176 for (int i = 0; i < versions.size(); i++) { 25177 List<String> segments = SQLUtil.parseNames(object.toString()); 25178 boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1), 25179 object.getGsqlparser().getDbVendor(), versions.get(i), true); 25180 if (result) { 25181 return result; 25182 } 25183 } 25184 } 25185 } catch (Exception e) { 25186 } 25187 25188 return false; 25189 } 25190 25191 public boolean isKeyword(String objectName) { 25192 if (objectName == null) 25193 return false; 25194 try { 25195 EDbVendor vendor = getOption().getVendor(); 25196 25197 List<String> versions = keywordChecker.getAvailableDbVersions(vendor); 25198 if (versions != null && versions.size() > 0) { 25199 for (int i = 0; i < versions.size(); i++) { 25200 List<String> segments = SQLUtil.parseNames(objectName); 25201 boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1), 25202 vendor, versions.get(i), false); 25203 if (result) { 25204 return result; 25205 } 25206 } 25207 } 25208 } catch (Exception e) { 25209 } 25210 25211 return false; 25212 } 25213 25214 public boolean isAggregateFunction(TFunctionCall func) { 25215 if (func == null) 25216 return false; 25217 return Arrays 25218 .asList(new String[] { "AVG", "COUNT", "MAX", "MIN", "SUM", "COLLECT", "CORR", "COVAR_POP", 25219 "COVAR_SAMP", "CUME_DIST", "DENSE_RANK", "FIRST", "GROUP_ID", "GROUPING", "GROUPING_ID", "LAST", 25220 "LISTAGG", "MEDIAN", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK", 25221 "STATS_BINOMIAL_TEST", "STATS_CROSSTAB", "STATS_F_TEST", "STATS_KS_TEST", "STATS_MODE", 25222 "STATS_MW_TEST", "STATS_ONE_WAY_ANOVA", "STATS_WSR_TEST", "STDDEV", "STDDEV_POP", "STDDEV_SAMP", 25223 "SYS_XMLAGG", "VAR_ POP", "VAR_ SAMP", "VARI ANCE", "XMLAGG", "ARRAY_AGG" }) 25224 .contains(func.getFunctionName().toString().toUpperCase()); 25225 } 25226 25227 public boolean isConstant(TObjectName object) { 25228 if (object == null || object.getGsqlparser() == null) 25229 return false; 25230 List<String> constants = Arrays.asList(new String[] { "NEXTVAL", "CURRVAL", "SYSDATE", "CENTURY", "YEAR", 25231 "MONTH", "DAY", "HOUR", "MINUTE", "SECOND" }); 25232 List<String> segments = SQLUtil.parseNames(object.toString()); 25233 // sequence.NEXTVAL or sequence.CURRVAL is a sequence reference, not a constant 25234 // This syntax is used by Oracle, Snowflake, and accepted by other vendors for compatibility 25235 String columnNameOnly = object.getColumnNameOnly(); 25236 if (segments.size() > 1 && ("NEXTVAL".equalsIgnoreCase(columnNameOnly) || "CURRVAL".equalsIgnoreCase(columnNameOnly))) { 25237 return false; 25238 } 25239 boolean result = constants.indexOf(segments.get(segments.size() - 1).toUpperCase()) != -1; 25240 if (result) { 25241 return result; 25242 } 25243 if (isKeyword(object)) { 25244 return true; 25245 } 25246 return false; 25247 } 25248 25249 private Pair3<Long, Long, Integer> convertCoordinate(Pair3<Long, Long, String> position) { 25250// if (ModelBindingManager.getGlobalOption()!=null && ModelBindingManager.getGlobalOption().isIgnoreCoordinate()) { 25251// return new Pair3<>(-1L, -1L, -1); 25252// } 25253 return new Pair3<Long, Long, Integer>(position.first, position.second, 25254 ModelBindingManager.getGlobalSqlInfo().getIndexOf(position.third)); 25255 } 25256 25257 /** 25258 * Analyze MDX SELECT statement to generate data lineage. 25259 * Maps MDX cube as source table, measures/dimensions as columns, 25260 * and creates dataflow relationships to the result set. 25261 */ 25262 private void analyzeMdxSelectStmt(gudusoft.gsqlparser.stmt.mdx.TMdxSelect stmt) { 25263 // Get cube name from FROM clause 25264 gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode cube = stmt.getCube(); 25265 if (cube == null) { 25266 return; 25267 } 25268 25269 String cubeName = getMdxIdentifierName(cube); 25270 Table cubeTable = modelFactory.createTableByName(cubeName, false); 25271 25272 // Collect all MDX identifier references from axes and WHERE clause 25273 List<String> measureNames = new ArrayList<String>(); 25274 List<String> dimensionNames = new ArrayList<String>(); 25275 25276 // Process axes (COLUMNS, ROWS, etc.) 25277 if (stmt.getAxes() != null) { 25278 for (int i = 0; i < stmt.getAxes().size(); i++) { 25279 gudusoft.gsqlparser.nodes.mdx.TMdxAxisNode axis = stmt.getAxes().getElement(i); 25280 if (axis.getExpNode() != null) { 25281 collectMdxReferences(axis.getExpNode(), measureNames, dimensionNames); 25282 } 25283 } 25284 } 25285 25286 // Process WHERE clause (slicer dimension) 25287 if (stmt.getWhere() != null && stmt.getWhere().getFilter() != null) { 25288 collectMdxReferences(stmt.getWhere().getFilter(), measureNames, dimensionNames); 25289 } 25290 25291 // Process WITH MEMBER definitions 25292 if (stmt.getWiths() != null) { 25293 for (int i = 0; i < stmt.getWiths().size(); i++) { 25294 gudusoft.gsqlparser.nodes.mdx.TMdxWithNode withNode = stmt.getWiths().getElement(i); 25295 if (withNode.getNameNode() != null) { 25296 String withName = getMdxIdentifierName(withNode.getNameNode()); 25297 // Calculated members are treated as derived measures 25298 if (withName.toLowerCase().startsWith("[measures].") 25299 || withName.toLowerCase().startsWith("measures.")) { 25300 measureNames.add(withName); 25301 } 25302 } 25303 // Also collect references used in the WITH expression 25304 if (withNode.getExprNode() != null) { 25305 collectMdxReferences(withNode.getExprNode(), measureNames, dimensionNames); 25306 } 25307 } 25308 } 25309 25310 // Create columns on the cube table for all referenced measures and dimensions 25311 Set<String> addedColumns = new LinkedHashSet<String>(); 25312 for (String measure : measureNames) { 25313 if (addedColumns.add(measure)) { 25314 modelFactory.createTableColumn(cubeTable, measure); 25315 } 25316 } 25317 for (String dimension : dimensionNames) { 25318 if (addedColumns.add(dimension)) { 25319 modelFactory.createTableColumn(cubeTable, dimension); 25320 } 25321 } 25322 25323 // Create result set with all referenced columns 25324 ResultSet resultSet = modelFactory.createResultSet(stmt, false); 25325 if (resultSet != null) { 25326 for (String colName : addedColumns) { 25327 TableColumn sourceCol = findTableColumnByName(cubeTable, colName); 25328 if (sourceCol != null) { 25329 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 25330 relation.setEffectType(EffectType.select); 25331 relation.addSource(new TableColumnRelationshipElement(sourceCol)); 25332 relation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 25333 resultSet.getRelationRows())); 25334 } 25335 } 25336 } 25337 } 25338 25339 private TableColumn findTableColumnByName(Table table, String name) { 25340 for (TableColumn col : table.getColumns()) { 25341 if (col.getName().equals(name)) { 25342 return col; 25343 } 25344 } 25345 return null; 25346 } 25347 25348 /** 25349 * Extract the display name from an MDX identifier node. 25350 * E.g., [Measures].[Departures NEAT] -> [Measures].[Departures NEAT] 25351 */ 25352 private String getMdxIdentifierName(gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode idNode) { 25353 StringBuilder sb = new StringBuilder(); 25354 for (int i = 0; i < idNode.getSegmentList().size(); i++) { 25355 if (i > 0) sb.append("."); 25356 gudusoft.gsqlparser.nodes.mdx.IMdxIdentifierSegment seg = idNode.getSegmentList().getElement(i); 25357 if (seg.getQuoting() == gudusoft.gsqlparser.nodes.mdx.EMdxQuoting.QUOTED) { 25358 sb.append("[").append(seg.getName()).append("]"); 25359 } else { 25360 sb.append(seg.getName()); 25361 } 25362 } 25363 return sb.toString(); 25364 } 25365 25366 /** 25367 * Recursively collect measure and dimension references from MDX expression tree. 25368 * Uses iterative DFS to avoid StackOverflow on deeply nested expressions. 25369 */ 25370 private void collectMdxReferences(gudusoft.gsqlparser.nodes.mdx.TMdxExpNode expr, 25371 List<String> measures, List<String> dimensions) { 25372 Deque<gudusoft.gsqlparser.nodes.mdx.TMdxExpNode> stack = new ArrayDeque<gudusoft.gsqlparser.nodes.mdx.TMdxExpNode>(); 25373 stack.push(expr); 25374 25375 while (!stack.isEmpty()) { 25376 gudusoft.gsqlparser.nodes.mdx.TMdxExpNode current = stack.pop(); 25377 if (current == null) continue; 25378 25379 if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode) { 25380 gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode idNode = 25381 (gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode) current; 25382 String name = getMdxIdentifierName(idNode); 25383 if (name.toLowerCase().startsWith("[measures].") 25384 || name.toLowerCase().startsWith("measures.")) { 25385 measures.add(name); 25386 } else if (idNode.getSegmentList().size() > 1) { 25387 // Multi-segment identifiers that aren't measures are dimensions 25388 dimensions.add(name); 25389 } 25390 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxSetNode) { 25391 gudusoft.gsqlparser.nodes.mdx.TMdxSetNode setNode = 25392 (gudusoft.gsqlparser.nodes.mdx.TMdxSetNode) current; 25393 if (setNode.getTupleList() != null) { 25394 for (int i = 0; i < setNode.getTupleList().size(); i++) { 25395 stack.push(setNode.getTupleList().getElement(i)); 25396 } 25397 } 25398 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxTupleNode) { 25399 gudusoft.gsqlparser.nodes.mdx.TMdxTupleNode tupleNode = 25400 (gudusoft.gsqlparser.nodes.mdx.TMdxTupleNode) current; 25401 if (tupleNode.getExprList() != null) { 25402 for (int i = 0; i < tupleNode.getExprList().size(); i++) { 25403 stack.push(tupleNode.getExprList().getElement(i)); 25404 } 25405 } 25406 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxBinOpNode) { 25407 gudusoft.gsqlparser.nodes.mdx.TMdxBinOpNode binOp = 25408 (gudusoft.gsqlparser.nodes.mdx.TMdxBinOpNode) current; 25409 if (binOp.getRightExprNode() != null) stack.push(binOp.getRightExprNode()); 25410 if (binOp.getLeftExprNode() != null) stack.push(binOp.getLeftExprNode()); 25411 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxFunctionNode) { 25412 gudusoft.gsqlparser.nodes.mdx.TMdxFunctionNode funcNode = 25413 (gudusoft.gsqlparser.nodes.mdx.TMdxFunctionNode) current; 25414 if (funcNode.getArguments() != null) { 25415 for (int i = 0; i < funcNode.getArguments().size(); i++) { 25416 stack.push(funcNode.getArguments().getElement(i)); 25417 } 25418 } 25419 } 25420 } 25421 } 25422 25423 /** 25424 * Analyze a Power Query M-language document for data lineage. 25425 * 25426 * Delegates to TPowerQueryAnalyzer to extract navigation chains and 25427 * NativeQuery embedded SQL, then feeds the results back through the 25428 * standard SQL analysis pipeline so the dataflow model contains 25429 * regular table/column lineage. 25430 */ 25431 private void analyzePowerQueryDocumentStmt(TPowerQueryDocumentStmt pqStmt) { 25432 TPowerQueryAnalyzer pqAnalyzer = new TPowerQueryAnalyzer(pqStmt); 25433 25434 if (option.getPowerQueryInnerVendor() != null) { 25435 pqAnalyzer.withExplicitInnerVendor(option.getPowerQueryInnerVendor()); 25436 } 25437 25438 PowerQueryLineageResult result = pqAnalyzer.analyze(); 25439 25440 if (result.isEmpty()) { 25441 for (String w : result.getWarnings()) { 25442 logger.warn("Power Query: " + w); 25443 } 25444 return; 25445 } 25446 25447 for (PowerQueryLineageResult.NativeQueryRef nq : result.getNativeQueryReferences()) { 25448 if (nq.innerParser != null && nq.innerParseReturnCode == 0) { 25449 for (int i = 0; i < nq.innerParser.sqlstatements.size(); i++) { 25450 analyzeCustomSqlStmt(nq.innerParser.sqlstatements.get(i)); 25451 } 25452 } 25453 } 25454 25455 for (PowerQueryLineageResult.NavigationRef nav : result.getNavigationReferences()) { 25456 if (nav.syntheticSelect != null && nav.resolvedVendor != null) { 25457 TGSqlParser synParser = new TGSqlParser(nav.resolvedVendor); 25458 synParser.sqltext = nav.syntheticSelect; 25459 int rc = synParser.parse(); 25460 if (rc == 0) { 25461 for (int i = 0; i < synParser.sqlstatements.size(); i++) { 25462 analyzeCustomSqlStmt(synParser.sqlstatements.get(i)); 25463 } 25464 } 25465 } 25466 } 25467 25468 for (String w : result.getWarnings()) { 25469 logger.warn("Power Query: " + w); 25470 } 25471 } 25472 25473}